/* Add client to struct, Init, print about it, check for start game. */ void ConnectClient (struct clientlist *clList, int fd) { struct client * user; user = (struct client *) malloc (sizeof(struct client)); AddClientToList (user, clList); InitUser (user, clList, fd); printf ("New client connected. FD=%d. #%d.\n", fd, clList->cnt); PrintToFDSuccessConnect (fd); PrintToAll(clList, StatusUsersConnecting(clList)); if ( clList->cnt == clList->maxPlayers ) { ReadyToStartGame (clList); } }
int main(int argc, char *argv[]) { fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() struct sockaddr_in remoteaddr; // client address unsigned ServerPort; // portnumber of server int fdmax,fdmax_used; // maximum file descriptor number and helper to find new max int listener; // listening socket descriptor int newfd; // newly accept()ed socket descriptor char buf[256]; // buffer for client data int nbytes; int addrlen; int i, j; int NewClient; // NewClient ID struct timeval timeout; // timeout int ret; struct ClientListType *ptrNewClient; // ptr to new & Active Client; struct ClientListType *ptrClientRightList; // array which contains rights of reg.Clients struct ActiveClientStructType ActiveClientStruct; // struct which contains array of active cl. // some command line parsing if (argc>1) { // first argument might be a port assignment if (*argv[1]=='?') { // ask for help printf("Usage : %s PortNum\n",argv[0]); exit(EXIT_SUCCESS); } else { ServerPort=atol(argv[1]); } } else { ServerPort=TCP_CLIENT_PORT; } // Init Client Access list InitClientAccessList(ptrClientRightAscList, &ptrClientRightList); // Init Active Client List InitActiveClientStruct(&ActiveClientStruct); printf("Setup instrument server version %s on port %d ...",VERSION, ServerPort); listener=InitTCPListener(ServerPort); if (listener<1) { perror("TCPListener"); } printf("success\n"); // setup master fd FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); FD_SET(listener, &master); // add the listener to the master set // keep track of the biggest file descriptor fdmax = listener; // so far, it's this one for(;;) { // main loop // setup fd's timeout and wait for incoming request read_fds = master; timeout.tv_sec=TCP_CLIENT_WDG; timeout.tv_usec=0; ret=select(fdmax+1, &read_fds, NULL, NULL, &timeout); if (ret == -1) { // select error we dare not to handle perror("select"); exit(EXIT_FAILURE); } if (ret) { // lets see what we got for(i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // new msg on i. socket ... if (i == listener) { // listener -> new connection request addrlen = sizeof(remoteaddr); if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, // first we have to accept &addrlen)) == -1) { perror("accept"); } else { //Valid client ? if ( ((ptrNewClient=ValidateAddress(&remoteaddr,ptrClientRightList))!=NULL) ) { //add new client to active list if ((NewClient=AddClientToList(&ActiveClientStruct,ptrNewClient,newfd))<0) { // couldn't add Client to list; printf("no available sockets for fd %d\n",newfd); close(newfd); // close connection } else { // give a positive msg to the log and keep track of maxfd printf("accepted new connection from %s\n", ActiveClientStruct.ptrActiveClientArray[NewClient].ClientName); FD_SET(newfd, &master); // add to master set if (newfd > fdmax) { // keep trackof the maximum fdmax = newfd; } } // endif AddClient } else { // couldn't find applicant in internal rights list, kick him out close(newfd); printf("deny access from %s closing..\n",inet_ntoa(remoteaddr.sin_addr)); } // endif ValidateAddress } // endif accept } else { // handle data from a clients if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { // got error or connection closed by client if (nbytes == 0) { // connection closed ret=RemoveClientFromList(&ActiveClientStruct,i); printf("instrumentserver: %s on socket %d hung up\n", ActiveClientStruct.ptrActiveClientArray[ret].ClientName, i); } else { perror("recv"); } // EndIf recv close(i); // bye! FD_CLR(i, &master); // remove from master set } else { // we got some data from a client // display whats in decimal for first ParseMsg(buf,nbytes,&ActiveClientStruct); for(j = 0; j <= fdmax; j++) { // send to everyone if (FD_ISSET(j, &master)) { // except the listener and sender if (j != listener && j != i) { if (send(j, buf, nbytes, 0) == -1) { perror("send"); } //endif send } // sender and listener } // someone in master list } //endfor all clients } } } } } else { for (i = 0; i <= fdmax; i++) { if (FD_ISSET(i,&master)) { printf("+"); fdmax_used=i; // find out what the highest used fd is } else { printf("."); } } printf("\n"); fdmax=fdmax_used; // garbage collection on max fdnum } } // for main loop // release used memory ReleaseActiveClientStruct(&ActiveClientStruct); // relase memory of ActiveClientStruct ReleaseClientAccessList(ptrClientRightList); // relase memory of ClientRightList return EXIT_SUCCESS; }