From 1e00753cb274072fc2e847e82a56e53d0186b1eb Mon Sep 17 00:00:00 2001 From: Navi Date: Sat, 18 Apr 2020 23:02:35 -0500 Subject: [PATCH] apply select model to client --- Zeus-Client/client.cpp | 101 ++++++++++++++++++++++++++++++----------- Zeus-Server/server.cpp | 33 ++++++++++++-- 2 files changed, 103 insertions(+), 31 deletions(-) diff --git a/Zeus-Client/client.cpp b/Zeus-Client/client.cpp index 11dab63..a667693 100644 --- a/Zeus-Client/client.cpp +++ b/Zeus-Client/client.cpp @@ -14,6 +14,7 @@ enum CMD { CMD_LOGIN_RESULT, CMD_LOGOUT, CMD_LOGOUT_RESULT, + CMD_NEW_USER_JOIN, CMD_ERROR }; @@ -57,6 +58,54 @@ struct LogoutResult : public Header { int result; }; +struct NewUserJoin : public Header { + NewUserJoin() { + length = sizeof(NewUserJoin); + cmd = CMD_NEW_USER_JOIN; + sock = 0; + } + int sock; +}; + +int processor(SOCKET _cli) { + + // Buffer + char recvBuf[1024] = {}; + // Recv + int recvlen = recv(_cli, recvBuf, sizeof(Header), 0); + Header *_header = (Header *)recvBuf; + if (recvlen <= 0) { + cout << "Disconnected" << endl; + return -1; + } + + switch (_header->cmd) { + case CMD_LOGIN_RESULT: + { + recv(_cli, recvBuf + sizeof(Header), _header->length - sizeof(Header), 0); + LoginResult* _loginResult = (LoginResult *)recvBuf; + cout << "Recieve Message: " << _loginResult->cmd << " Data Length: " << _loginResult->length << " Result: " << _loginResult->result << endl; + break; + } + case CMD_LOGOUT_RESULT: + { + recv(_cli, recvBuf + sizeof(Header), _header->length - sizeof(Header), 0); + LogoutResult* _logoutResult = (LogoutResult *)recvBuf; + cout << "Recieve Message: " << _logoutResult->cmd << " Data Length: " << _logoutResult->length << " Result: " << _logoutResult->result << endl; + break; + } + case CMD_NEW_USER_JOIN: + { + recv(_cli, recvBuf + sizeof(Header), _header->length - sizeof(Header), 0); + NewUserJoin* _userJoin = (NewUserJoin *)recvBuf; + cout << "Recieve Message: " << _userJoin->cmd << " Data Length: " << _userJoin->length << " New User: " << _userJoin->sock << endl; + break; + } + } + + return 0; +} + int main() { WORD version = MAKEWORD(2, 2); WSADATA data; @@ -85,35 +134,34 @@ int main() { } while (true) { - // Handle request - char cmdBuf[128] = {}; - scanf("%s", cmdBuf); - if (0 == strcmp(cmdBuf, "quit")) { - cout << "Quit" << endl; + // Select + fd_set fdRead; + FD_ZERO(&fdRead); + FD_SET(_sock, &fdRead); + timeval t = { 0, 5e5 }; + int ret = select(_sock, &fdRead, NULL, NULL, &t); + + if (ret < 0) { + cout << "Select quits" << endl; break; - } else if (0 == strcmp(cmdBuf, "login")) { - Login _login; - strcpy(_login.username, "navi"); - strcpy(_login.password, "123456"); - // Send - send(_sock, (char *)&_login, sizeof(Login), 0); - // Recv - LoginResult _result = {}; - recv(_sock, (char *)&_result, sizeof(LoginResult), 0); - cout << "Login result: " << _result.result << endl; - } else if (0 == strcmp(cmdBuf, "logout")) { - Logout _logout; - strcpy(_logout.username, "navi"); - // Send - send(_sock, (char *)&_logout, sizeof(Logout), 0); - // Recv - LogoutResult _result = {}; - recv(_sock, (char *)&_result, sizeof(LogoutResult), 0); - cout << "Logout result: " << _result.result << endl; } - else { - cout << "Invaild input" << endl; + + // If socket is inside the set + if (FD_ISSET(_sock, &fdRead)) { + FD_CLR(_sock, &fdRead); + // Handle request + if (-1 == processor(_sock)) { + break; + } } + + // Handle other services + cout << "Other services..." << endl; + Login _login; + strcpy(_login.username, "Navi"); + strcpy(_login.password, "123456"); + send(_sock, (const char *)&_login, sizeof(Login), 0); + Sleep(500); } @@ -122,6 +170,7 @@ int main() { WSACleanup(); + cout << "Quit." << endl; getchar(); return 0; } diff --git a/Zeus-Server/server.cpp b/Zeus-Server/server.cpp index 541949b..331d39d 100644 --- a/Zeus-Server/server.cpp +++ b/Zeus-Server/server.cpp @@ -14,6 +14,7 @@ enum CMD { CMD_LOGIN_RESULT, CMD_LOGOUT, CMD_LOGOUT_RESULT, + CMD_NEW_USER_JOIN, CMD_ERROR }; @@ -57,6 +58,15 @@ struct LogoutResult : public Header { int result; }; +struct NewUserJoin : public Header { + NewUserJoin() { + length = sizeof(NewUserJoin); + cmd = CMD_NEW_USER_JOIN; + sock = 0; + } + int sock; +}; + vector g_clients; int processor(SOCKET _cli) { @@ -67,7 +77,7 @@ int processor(SOCKET _cli) { int recvlen = recv(_cli, recvBuf, sizeof(Header), 0); Header *_header = (Header *)recvBuf; if (recvlen <= 0) { - cout << "Client quits" << endl; + cout << "Client " << _cli << " quits" << endl; return -1; } @@ -76,7 +86,7 @@ int processor(SOCKET _cli) { { recv(_cli, recvBuf + sizeof(Header), _header->length - sizeof(Header), 0); Login* _login = (Login *)recvBuf; - cout << "Command: " << _login->cmd << " Data length: " << _login->length << " Username: " << _login->username << " Password: " << _login->password << endl; + cout << "Client " << _cli << " Command: " << _login->cmd << " Data length: " << _login->length << " Username: " << _login->username << " Password: " << _login->password << endl; // Judge username and password // Send LoginResult _result; @@ -87,7 +97,7 @@ int processor(SOCKET _cli) { { recv(_cli, recvBuf + sizeof(Header), _header->length - sizeof(Header), 0); Logout* _logout = (Logout *)recvBuf; - cout << "Command: " << _logout->cmd << " Data length: " << _logout->length << " Username: " << _logout->username << endl; + cout << "Client " << _cli << " Command: " << _logout->cmd << " Data length: " << _logout->length << " Username: " << _logout->username << endl; // Send LogoutResult _result; send(_cli, (char *)&_result, sizeof(LogoutResult), 0); @@ -157,7 +167,7 @@ int main() { FD_SET(g_clients[n], &fdRead); } - timeval t = {0, 0}; + timeval t = {0, 5e5}; int ret = select(_sock + 1, &fdRead, &fdWrite, &fdExcept, &t); if (ret < 0) { @@ -165,6 +175,7 @@ int main() { break; } + // If socket is inside the set if (FD_ISSET(_sock, &fdRead)) { FD_CLR(_sock, &fdRead); // Accept @@ -173,9 +184,18 @@ int main() { SOCKET _cli = accept(_sock, (sockaddr *)&clientAddr, &addrlen); if (INVALID_SOCKET == _cli) { cout << "Invaild client socket" << endl; + continue; } + + // Broadcast + for (int n = (int)g_clients.size() - 1; n >= 0; n--) { + NewUserJoin userJoin; + userJoin.sock = _cli; + send(g_clients[n], (const char *)&userJoin, sizeof(NewUserJoin), 0); + } + g_clients.push_back(_cli); - cout << "New client: " << inet_ntoa(clientAddr.sin_addr) << endl; + cout << "New client " << _cli << " : " << inet_ntoa(clientAddr.sin_addr) << "-" << clientAddr.sin_port << endl; } // Handle request @@ -187,6 +207,9 @@ int main() { } } } + + // Handle other services + cout << "Other services..." << endl; } // Close