#include #include #include #include #include #include #include #include #include #include #include #define BUFFER_SIZE 256 #define NOPORT_RET 10 #define INVALID_PORT_RET 20 #define BINDERR_RET 30 #define LISTENERR_RET 35 using namespace std; class Game { private: int upper; int lower; int count; int answer; public: Game(void) { this->reset(); } int get_upper() { return this->upper; } int get_lower() { return this->lower; } int get_count() { return this->count; } int get_answer() { return this->answer; } void reset() { this->upper = 999; this->lower = 0; this->count = 0; this->answer = rand() % 1000; } bool guess(int num) { this->count++; if (num == answer) return true; if (num > answer && num < this->upper) this->upper = num; else if (num < answer && num > this->lower) this->lower = num; return false; } }; int main(int argc, char const *argv[]) { // initialize game srand(time(nullptr)); Game game; // no port specified if (argc < 1) { cerr << "No port provided!" << endl << "Usage: server " << endl; return NOPORT_RET; } int port = atoi(argv[1]); if (port < 0 || port >= 65536) { cerr << "Invalid port! port range: 0 ~ 65535" << endl; return INVALID_PORT_RET; } int sockfd = 0; struct sockaddr_in server_info; // create tcp socket sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { cerr << "Failed to create socket" << endl; } // setup server info bzero((char *) &server_info, sizeof(server_info)); server_info.sin_family = PF_INET; server_info.sin_addr.s_addr = INADDR_ANY; server_info.sin_port = htons(port); // bind if (bind(sockfd, (struct sockaddr *) &server_info, sizeof(server_info)) == -1) { cerr << "Cannot bind socker." << endl; close(sockfd); return BINDERR_RET; } // only one connection at the same time if (listen(sockfd, 1) == -1) { cerr << "Cannot listen to socket." << endl; return LISTENERR_RET; } cout << "Server up. Waiting connection..." << endl; int client_sockfd = 0; struct sockaddr_in client_info; socklen_t addrlen = sizeof(client_info); while (true) { client_sockfd = accept(sockfd, (struct sockaddr *) &client_info, &addrlen); if (client_sockfd < 0) { cout << "Error occurred while handling request from client." << endl; continue; } // retrieve client info char ip[INET_ADDRSTRLEN]; uint16_t port; inet_ntop(AF_INET, &client_info.sin_addr, ip, sizeof(ip)); port = ntohs(client_info.sin_port); cout << "New client from " << ip << ":" << port << " has connected!" << endl; // reset for new client game.reset(); while (true) { // clear buffer for receive message char buffer[BUFFER_SIZE]; memset(buffer, 0, sizeof(buffer)); // wait message if (recv(client_sockfd, buffer, sizeof(buffer), 0) <= 0) { // closed connection cout << "Disconnected." << endl; break; } int guess = atoi(buffer); #ifdef DEBUG cout << guess << endl; #endif // message stringstream ss; const char * msg; #ifdef DEBUG cout << msg << endl; #endif // generate payload if (game.guess(guess)) { // win ss << game.get_answer() << ":" << game.get_answer() << ":" << game.get_count(); // new turn for this client game.reset(); } else { ss << game.get_lower() << ":" << game.get_upper() << ":" << game.get_count(); } msg = ss.str().c_str(); // send to client send(client_sockfd, msg, strlen(msg), 0); } } close(sockfd); return 0; }