void PGameServer::Update() { if ( ServerSock->newConnection() ) { int clid = Server->NewClient(); if ( clid != -1 ) { Console->Print( GREEN, BLACK, "[Info] Gameserver: client [%i] connected", clid ); PClient *Client = Server->GetClient( clid ); if ( Client->getTCPConn() ) Console->Print( RED, BLACK, "WARNING: Client %d : TCP Socket NOT NULL before allocation.", Client->GetID() ); ConnectionTCP* tcpConn = ServerSock->getTCPConnection(); Client->setTCPConnection( tcpConn ); //ConnectionUDP* udpConn = ServerSock->getUDPConnection(); //Client->setUDPConnection(udpConn); Console->Print( "Client address: %s", Client->GetAddress() ); ++mNumClients; PGameState *state = new PGameState(); ClientStates.insert( std::make_pair( Client, state ) ); state->TCP.mState = PGameState::TCP::GS_CONNECTED; // add the new connected client to the global clientmanager for further use in chat, etc... ClientManager->addClientToList( Client ); } else { Console->Print( YELLOW, BLACK, "[Notice] Gameserver: Client connection refused (server full?)" ); } } /*** temp check ***/ for ( PClientMap::iterator it = ClientManager->getClientListBegin(); it != ClientManager->getClientListEnd(); it++ ) { if ( !it->second ) { Console->Print( RED, BLACK, "PANIC: NULL Client found in ClientManager Clients Map." ); } } /*** end temp check ***/ for ( GameStateMap::iterator i = ClientStates.begin(); i != ClientStates.end(); ) { PClient *Client = i->first; PGameState *State = i->second; // node gets erased in FinalizeClient, increment iterator now ++i; if ( !ProcessClient( Client, State ) ) FinalizeClient( Client, State ); } }
int main(int argc, char ** argv) { int lsock; struct ClientNode * clients = NULL; int port; if(argc == 1) port = PORT_NUM; else return 1; printf(" Server v0.01\n"); lsock = CreateSocket(port); if (lsock == -1) return 1; for(;;) { /**/ fd_set readfds; int maxDs = lsock; int res; FD_ZERO(&readfds); FD_SET(lsock, &readfds); struct ClientNode * cl, *prev; for (cl = clients; cl!=NULL; cl = cl->next) { FD_SET(cl->fd, &readfds); if(cl->fd > maxDs) maxDs = cl->fd; } res = select(maxDs+1, &readfds, NULL, NULL, NULL); if(res<1) { /*handle error*/ } if(FD_ISSET(lsock, &readfds)) { clients = AddClient(lsock, clients); printf("new client connected\n"); } prev = clients; for(cl = clients; cl != NULL; cl = cl->next) { if(FD_ISSET(cl->fd, &readfds)) { /*read data, process it*/ int status; printf("new data arrives from client\n"); status = ProcessClient(cl); if(1 == status) { cl = DeleteClient(cl, prev, &clients); if(cl == NULL) break; } } prev = cl; } } return 0; }
void PPatchServer::Update() { //ServerSock->update(); if(ServerSock->newConnection()) { int clid = Server->NewClient(); if(clid!=-1) { Console->Print(GREEN, BLACK, "Patchserver: client [%i] connected", clid); PClient *Client = Server->GetClient(clid); ConnectionTCP* tcpConn = ServerSock->getTCPConnection(); Client->setTCPConnection(tcpConn); Console->Print("Client address: %s", Client->GetAddress()); //++mNumClients; PPatchState *state = new PPatchState(); ClientStates.insert(std::make_pair(Client, state)); state->mState = PPatchState::PS_CONNECTED; } else { Console->Print("Patchserver: Client connection refused (server full?)"); } } for(PatchStateMap::iterator i=ClientStates.begin(); i!=ClientStates.end();) { PClient *Client = i->first; PPatchState *State = i->second; // node gets erased in FinalizeClient, increment iterator now ++i; if(!ProcessClient(Client, State)) { FinalizeClient(Client, State); } } }
int PerformOperation(short port) { int acceptFd = 0; struct sockaddr_in sin; socklen_t sinlen = sizeof(sin); int fd = 0; int blocking = 1; int reuseaddr = 1; int devpoll = 0; int pollresult = 0; struct pollfd dp_fds[MAXSET]; struct dvpoll pollset; int procClient = 0; int i = 0; /* create devpoll fd */ if ((devpoll = open("/dev/poll", O_RDWR)) == -1) { printf("devpoll can't be opened: %s(%d)\n", strerror(errno), errno); exit(0); } /* create the accept socket */ acceptFd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (acceptFd == -1) { /* Error creating accept fd */ printf("Error creating socket: %s\n", strerror(errno)); exit(0); } /* set socket opt to reuse address */ if (setsockopt(acceptFd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)) == -1) { printf("Error w/ setsockopt: %s\n", strerror(errno)); close(acceptFd); exit(0); } /* setup the accept fd as nonblocking */ if (ioctl(acceptFd, FIONBIO, &blocking) == -1) { /* error setting the nonblocking of fd */ printf("Error setting FIONBIO: %s\n", strerror(errno)); close(acceptFd); exit(0); } /* bind the socket to the port */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = INADDR_ANY; if (bind(acceptFd, (struct sockaddr*)&sin, sizeof(sin))==-1) { printf("Error binding socket: %s\n", strerror(errno)); close(acceptFd); exit(0); } /* setup the listen queue */ if (listen(acceptFd, 1) == -1) { printf("Error listening: %s\n", strerror(errno)); close(acceptFd); exit(0); } /* Add to dev poll queue */ Add(devpoll, acceptFd); while (1) { /* Get and service any active fd */ pollset.dp_fds = dp_fds; pollset.dp_nfds = MAXSET; pollset.dp_timeout = -1; if ((pollresult = DoPoll(devpoll, &pollset)) == -1) { printf("Error w/ the polling: %s(%d)\n", strerror(errno), errno); exit(0); } for (i = 0; i < pollresult; i++) { /* if accept then accept the conn and add it to the devpoll */ if (pollset.dp_fds[i].fd == acceptFd) { fd = Accept(acceptFd); Add(devpoll, fd); } else { /* if a client fd then get the data and echo back */ procClient = ProcessClient(pollset.dp_fds[i].fd); if (procClient == 0) { /* client closed conn remove it from devpoll */ Remove(devpoll, fd); } } } } }