
服務器端:
#include<WinSock2.h> #include<Windows.h> #include<stdio.h> #include<iostream> #pragma comment(lib,"ws2_32.lib") enum CMD { CMD_Login,CMD_Logout,CMD_ERROR }; //包頭 struct DataHeader { short dataLength; short cmd; }; //包體 struct Login { char username[32]; char password[32]; }; struct LoginResult { int result; }; struct Logout { char username[32]; }; struct LogoutResult { int result; }; int main() { WORD ver = MAKEWORD(2, 2); WSADATA dat; //WinSocket啟動 WSAStartup(ver, &dat); //1、建立一個socket SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //AF_INET創建一個IPV4的套接字,SOCK_STREAM面向數據流的,IPPROTO_TCP TCP if (INVALID_SOCKET == _sock) { printf("ERROR:建立失敗!\n"); } //2.綁定 sockaddr_in _sin = {}; //創建網絡地址 _sin.sin_family = AF_INET; _sin.sin_port = htons(4567); //Host to Network Short _sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // IP地址 if (bind(_sock, (sockaddr *)&_sin, sizeof(_sin)) == SOCKET_ERROR) { printf("ERROR:綁定失敗!\n"); } else { printf("服務器端綁定成功......\n"); } //3.監聽網絡端口 if (listen(_sock, 5) == SOCKET_ERROR)//第二個參數為最大等待多少人可以同時連接 { printf("ERROR:監聽失敗!\n"); } else { printf("服務器端監聽成功......\n"); } //4.等待接收客戶端連接 sockaddr_in clientAddr = {}; int nAddrLen = sizeof(sockaddr_in); SOCKET _cSOCK = INVALID_SOCKET; _cSOCK = accept(_sock, (sockaddr *)&clientAddr, &nAddrLen); if (_cSOCK == INVALID_SOCKET) { printf("ERROR:無效客戶端SOCKET!\n"); } printf("新客戶端加入:Socket=%d,IP = %s\n",(int)_cSOCK, inet_ntoa(clientAddr.sin_addr));//inet_ntoa(clientAddr.sin_addr)將接收到的IP地址轉化為字符串 while (1) { DataHeader header = {}; //5.接收客戶端新數據 int nLen = recv(_cSOCK, (char *)&header, sizeof(DataHeader), 0); if (nLen <= 0) { printf("客戶端已退出!任務結束!"); break; } printf("收到命令:%s,數據長度:%d\n",header.cmd,header.dataLength); switch (header.cmd){ case CMD_Login: { Login login = {}; recv(_cSOCK, (char *)&login, sizeof(Login), 0); //忽略判斷用戶密碼是否正確的過程 LoginResult ret = { 1 }; send(_cSOCK, (char *)&header, sizeof(DataHeader), 0); //先發消息頭 send(_cSOCK, (char *)&ret, sizeof(LoginResult), 0); //再發消息體 } case CMD_Logout: { Logout logout = {}; recv(_cSOCK, (char *)&logout, sizeof(Logout), 0); //忽略判斷用戶密碼是否正確的過程 LogoutResult let = { 1 }; send(_cSOCK, (char *)&header, sizeof(DataHeader), 0); //先發消息頭 send(_cSOCK, (char *)&let, sizeof(LogoutResult), 0); //再發消息體 } break; default: header.cmd = CMD_ERROR; header.dataLength = 0; send(_cSOCK, (char *)&header.cmd, sizeof(header), 0); break; } } //8.關閉自身的socket closesocket(_sock); //WinSocket關閉 WSACleanup(); system("pause"); return 0; }
客戶端:
#include<WinSock2.h> #include<Windows.h> #include<stdio.h> #pragma comment(lib,"ws2_32.lib") enum CMD { CMD_Login, CMD_Logout, CMD_ERROR }; //包頭 struct DataHeader { short dataLength; short cmd; }; //包體 struct Login { char username[32]; char password[32]; }; struct LoginResult { int result; }; struct Logout { char username[32]; }; struct LogoutResult { int result; }; int main() { WORD ver = MAKEWORD(2, 2); WSADATA dat; WSAStartup(ver, &dat); //1.建立一個socket SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == _sock) { printf("ERROR:建立失敗!\n"); } else{ printf("客戶端綁定成功......\n"); } //2.連接服務器 sockaddr_in _sin = {}; //創建網絡地址 _sin.sin_family = AF_INET; _sin.sin_port = htons(4567); //Host to Network Short _sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//inet_addr("127.0.0.1"); // IP地址 int ret = connect(_sock, (sockaddr *)&_sin, sizeof(sockaddr_in)); if (SOCKET_ERROR == ret) { printf("ERROR:連接失敗!\n"); } else { printf("客戶端連接成功......\n"); } while (true) { //3.輸入請求命令 char cmdBuff[128] = {}; scanf("%s", cmdBuff); //4.處理請求命令 if (0 == strcmp(cmdBuff, "exit")) { printf("收到exit命令,已退出1"); break; } else if (0 == strcmp(cmdBuff, "login")){ Login login = { "sutaoyu01", "sutaoyu01" }; DataHeader dh = { sizeof(login), CMD_Login }; //5.向服務器發送請求命令 //先發數據頭 send(_sock, (const char*)&dh, sizeof(dh), 0); //再發數據尾 send(_sock, (const char*)&login, sizeof(login), 0); //接收服務器返回的數據 DataHeader retHeader = {}; LoginResult resulrtRet = {}; //接收服務器發送的數據頭 recv(_sock, (char*)&retHeader, sizeof(retHeader), 0); //接收服務器發送的數據體 recv(_sock, (char*)&resulrtRet, sizeof(resulrtRet), 0); printf("LoginResult:%d\n", resulrtRet.result); } else if (0 == strcmp(cmdBuff, "logout")){ Logout logout = { "sutaoyu01"}; DataHeader dh = { sizeof(logout),CMD_Logout }; //5.向服務器發送請求命令 //先發數據頭 send(_sock, (const char*)&dh, sizeof(dh), 0); //再發數據尾 send(_sock, (const char*)&logout, sizeof(logout), 0); //接收服務器返回的數據 DataHeader retHeader = {}; LogoutResult resultRet = {}; //接收服務器發送的數據頭 recv(_sock, (char*)&retHeader, sizeof(retHeader), 0); //接收服務器發送的數據體 recv(_sock, (char*)&resultRet, sizeof(resultRet), 0); printf("LogoutResult:%d\n", resultRet.result); } else{ printf("不支持的命令,請重新輸入!"); } } //7.關閉套接字 closesocket(_sock); //WinSocket啟動 WSAStartup(ver, &dat); //WinSocket關閉 WSACleanup(); printf("已退出!"); getchar(); return 0; }
