void mpeServerTCP::threadedFunction() { while(isThreadRunning()){ if(shouldTriggerFrame){ float now = ofGetElapsedTimef(); float elapsed = (now - lastFrameTriggeredTime); //cout << "should trigger frame!" << endl; if(elapsed >= 1.0/framerate){ //cout << "triggered frame with framerate error of " << fabs( elapsed - 1.0/framerate) << endl; string message = "G,"+ofToString(currentFrame); if (newMessage){ message += currentMessage; newMessage = false; currentMessage = ""; } server.sendToAll(message); for(int i = 0; i < connections.size(); i++){ connections[i].ready = false; } shouldTriggerFrame = false; lastFrameTriggeredTime = now; currentFrame++; } } else { //check for dead clients bool lostConnection = false; for(int c = 0; c < numExpectedClients; c++){ if(connections[c].started && !server.isClientConnected(connections[c].tcpServerIndex)){ connections[c].started = false; lostConnection = true; } } if(allconnected && lostConnection){ ofLog(OF_LOG_NOTICE, "MPE :: Client Disconnected -- RESET"); //oops someone left printClientStatus(); currentFrame = 0; shouldTriggerFrame = false; allconnected = false; server.sendToAll("R"); } //cout << "All clients are connected! " << endl; for(int i = 0; i < server.getLastID(); i++){ if(!server.isClientConnected(i)){ continue; } string response = server.receive(i); if(response == ""){ continue; } // cout << "received a response " << response << endl; char first = response.at(0); if(first == 'L'){ //Listener connected listeners.push_back(i); } else if(first == 'S'){ //that's the start! int clientID = ofToInt(response.substr(1,1)); if(clientID < numExpectedClients){ vector<string> info = ofSplitString(response, ",", true, true); if(connections[clientID].started && currentFrame != 0){ //client already started, must have reset... allconnected = false; currentFrame = 0; shouldTriggerFrame = false; server.sendToAll("R"); } connections[clientID].tcpServerIndex = i; connections[clientID].started = true; connections[clientID].name = info[1]; cout << "Client ID " << clientID << " with response " << response << endl; //TODO: parse name printClientStatus(); } else{ ofLog(OF_LOG_ERROR, "Received Client ID " + ofToString(clientID) + " out of range"); } } else if(first == 'D'){ if(!allconnected){ continue; } vector<string> info = ofSplitString(response, ",", true, true); if(info.size() >= 3){ int clientID = ofToInt(info[1]); int fc = ofToInt(info[2]); if(fc == currentFrame){ //todo validate client id connections[clientID].ready = true; //cout << " client " << clientID << " is ready " << endl; } if(info.size() > 3){ newMessage = true; for(int i = 3; i < info.size(); i++){ currentMessage += ":" + info[i]; } //cout << "NEW FORMAT :: MESSSAGE IS " << currentMessage << endl; } } else { ofLog(OF_LOG_ERROR, "MPE Server :: Response String " + response + " Invalid size"); } } } if(!allconnected){ allconnected = true; for(int c = 0; c < connections.size(); c++){ if(!connections[c].started){ allconnected = false; break; } } if(allconnected){ shouldTriggerFrame = true; cout << "All clients connected!" << endl; } } //All connected and going else { bool allready = true; for(int c = 0; c < connections.size(); c++){ if(!connections[c].ready){ allready = false; break; } } if(allready){ shouldTriggerFrame = true; } } } ofSleepMillis(5); }//end while }
int main(int args, char *argv[]) { char message[100]; MainPlayerData toPlayerData; CandidateData toCandidateData; StatusType status; fd_set allSocket; fd_set readfds; int fdmax, k, l; int n; int playerIndex; int mainPlayerSelected = 0; int clientId; int playerAnswer; int level; int numberOfClient = 0; int yes = 1; int readResult; int listener; int acceptSocket; struct sockaddr_in server, client; int sin_size; int socket_in_allSocket; int nbytes; int i, j; char clientName[40]; initializeClientList(); createCashPrizeList(); sin_size = sizeof(struct sockaddr_in); FD_ZERO(&allSocket); FD_ZERO(&readfds); if (args < 2) { printf("Usage : %s <PORT>\n", argv[0]); exit(-1); } readResult = readQuestionFile("question.txt"); if (readResult < 0) { printf("Can't load the questions !"); exit(-1); } if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("socket() error!\n"); exit(-1); } server.sin_family = AF_INET; server.sin_port = htons(atoi(argv[1])); server.sin_addr.s_addr = INADDR_ANY; bzero(&(server.sin_zero), 8); setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); if (bind(listener, (struct sockaddr*) &server, sizeof(struct sockaddr)) == -1) { printf("bind() error!\n"); exit(-1); } //listen if (listen(listener, 2) == -1) { perror("listen"); exit(3); } FD_SET(listener, &allSocket); fdmax = listener; printf("\t<<<Gameshow GHE NONG - AI LA TRIEU PHU>>>\n"); while (1) { readfds = allSocket; /* On error, -1 is returned, select() and pselect() return the number of file descriptors */ if (mainPlayerSelected == 0) { if (select(fdmax + 1, &readfds, NULL, NULL, NULL ) == -1) { perror("select"); printf("errno = %d.\n", errno); exit(4); } } for (i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &readfds)) { //printf("isset i=%d\n", i); if (i == listener) { acceptSocket = accept(listener, (struct sockaddr*) &client, &sin_size); printf("Listener : %d accept %d\n", listener, acceptSocket); //in dia chi ip printf("\n client address %s\n", inet_ntoa(client.sin_addr)); if (acceptSocket == -1) { perror("accept"); } else if (isClientListFull()) { clientId = NULL_ID; send(acceptSocket, &clientId, sizeof clientId, 0); close(acceptSocket); //FD_CLR(acceptSocket, &allSocket); } else { FD_SET(acceptSocket, &allSocket); printf("Server connected with socket %d\n", acceptSocket); addClient(acceptSocket); clientId = acceptSocket; if (acceptSocket > fdmax) { fdmax = acceptSocket; //printf("Now fdmax is : %d\n", fdmax); } send(acceptSocket, &clientId, sizeof clientId, 0); numberOfClient = getNumberOfClient(); printf("We're now having %d clients connected !\n", numberOfClient); } } else { // printf("i before switch = %d Fmax=%d\n", i, fdmax); switch_case: switch (getClientStatus(i)) { case CONNECTED: if ((nbytes = recv(i, &toCandidateData, sizeof toCandidateData, 0)) <= 0) { printf( "Server stopped connecting to client id %d\n", i); close(i); removeClient(i); printf("%d clients left !\n", getNumberOfClient()); FD_CLR(i, &allSocket); break; } else { recv(i, clientName, sizeof clientName, 0); setClientStatus(i, WAITING, clientName); strcpy(message, "Welcome : "); strcat(message, clientName); strcat(message, "\n"); strcpy(toCandidateData.message, message); toCandidateData.status = WAITING; send(i, &toCandidateData, sizeof toCandidateData, 0); printClientList(); /* check if have enough 6 clients, so we can start the game */ if (readyToStart()) { printf("We can start the game !!\n"); k = randomNumber(NUMBERS_PER_QUES); //send question to all the clients // for (j = 0; j < BACKLOG; j++) { setCompetition(j); copyQuestion(&(toCandidateData.question), questLib[0][k]); toCandidateData.ansTime = 0; toCandidateData.status = COMPETING; strcpy(toCandidateData.message, QUICK_QUESTION_MESSAGE); send(clientInfo[j].id, &toCandidateData, sizeof(CandidateData), 0); } //get the answer back from them // for (j = 0; j < BACKLOG; j++) { if (recv(clientInfo[j].id, &toCandidateData, sizeof toCandidateData, 0) <= 0) { printf( "Server stopped connecting to client id %d\n", i); close(i); removeClient(i); printf("%d clients left !\n", getNumberOfClient()); FD_CLR(i, &allSocket); } else { clientInfo[j].quick_answer = toCandidateData.answer; clientInfo[j].ansTime = toCandidateData.ansTime; } } //printf("Sending question done!\n"); printClientsAnswerList(); //select the main player // playerIndex = selectMainPlayer(questLib[0][k], BACKLOG); printf( "Our answer for the quick question : %d\n", questLib[0][k].ans); printf("====MAIN PLAYER SELECTED : %s ====\n", clientInfo[playerIndex].clientName); printClientStatus(clientInfo[playerIndex].id); startGame(playerIndex); for (j = 0; j < BACKLOG; j++) { if (j != playerIndex) { strcpy(toCandidateData.message, JOINER_MESSAGE); } else { strcpy(toCandidateData.message, MAIN_PLAYER_SELECTED); strcpy(toPlayerData.name, clientInfo[j].clientName); } toCandidateData.status = getClientStatus( clientInfo[j].id); send(clientInfo[j].id, &toCandidateData, sizeof(CandidateData), 0); } printClientList(); //printf("Current i = %d\n", i); i = clientInfo[playerIndex].id; mainPlayerSelected = 1; goto switch_case; // break; } else { sprintf(message, "We now have %d players online, please wait until we have more %d client(s) !\n", getNumberOfClient(), BACKLOG - getNumberOfClient()); strcpy(toCandidateData.message, message); send(i, &toCandidateData, sizeof toCandidateData, 0); } } break; case JOINING: //printf("[JOINING] Current i = %d\n", i); // i = 0; // if (mainPlayerSelected == 1) { // if ((nbytes = recv(i, &toCandidateData, // sizeof toCandidateData, 0)) <= 0) { // printf( // "Server stopped connecting to client id %d\n", // i); // close(i); // removeClient(i); // printf("%d clients left !\n", // getNumberOfClient()); // FD_CLR(i, &allSocket); // break; // } // } break; case PLAYING: mainPlayerSelected = 1; initializeMainPlayerData(&toPlayerData); level = 1; do { selectQuestion(level, &toPlayerData); send(clientInfo[playerIndex].id, &toPlayerData, sizeof toPlayerData, 0); for (n = 0; n < BACKLOG; n++) { if (clientInfo[n].status == JOINING) { send(clientInfo[n].id, &toPlayerData, sizeof toPlayerData, 0); } } if (recv(i, &playerAnswer, sizeof playerAnswer, 0) <= 0) { printf( "Server stopped connecting to client id %d\n", i); close(i); removeClient(i); printf("%d clients left !\n", getNumberOfClient()); FD_CLR(i, &allSocket); gameFinish(&toPlayerData,END); for (n = 0; n < BACKLOG; n++) { if (clientInfo[n].status == JOINING) { toPlayerData.status = FINISHED; send(clientInfo[n].id, &toPlayerData, sizeof toPlayerData, 0); close(clientInfo[n].id); removeClient(clientInfo[n].id); FD_CLR(clientInfo[n].id, &allSocket); } } continue; } if (playerAnswer == RIGHT) { printf("Good job! The player gave a right answer!\n"); increaseQuestion(&toPlayerData); //tra loi dung o cau hoi so 15 if (level == MAX_LEVEL) { wonGame(&toPlayerData); send(i, &toPlayerData, sizeof toPlayerData, 0); for (n = 0; n < BACKLOG; n++) { if (clientInfo[n].status == JOINING) { send(clientInfo[n].id, &toPlayerData, sizeof toPlayerData, 0); close(clientInfo[n].id); removeClient(clientInfo[n].id); FD_CLR(clientInfo[n].id, &allSocket); } } close(i); removeClient(i); FD_CLR(i, &allSocket); exit(1); } level = level + 1; } else { endGame(&toPlayerData, playerAnswer); gameFinish(&toPlayerData,playerAnswer); send(i, &toPlayerData, sizeof toPlayerData, 0); for (n = 0; n < BACKLOG; n++) { if (clientInfo[n].status == JOINING) { toPlayerData.status = FINISHED; send(clientInfo[n].id, &toPlayerData, sizeof toPlayerData, 0); close(clientInfo[n].id); removeClient(clientInfo[n].id); FD_CLR(clientInfo[n].id, &allSocket); } } close(i); removeClient(i); printf("%d clients left !\n", getNumberOfClient()); FD_CLR(i, &allSocket); } } while (playerAnswer == RIGHT && level <= MAX_LEVEL); printf("The game of player : %s ended !\n", toPlayerData.name); exit(1); break; default: break; } } } } } }