https://blog.csdn.net/antony1776/article/details/73717666
实现C/S程序,加上登录注册聊天等功能。
然后要做个协议的样子出来。
比如说注册功能要把用户名密码一起发送过去,然后在前面在加一个标志,表示用的是哪个操作。就相当于是一个协议。
然后下面的代码并没有实现协议。
写的很累赘,就是问来问去
struct user { int flag; string user; string password; int length; char option[MAX_BUF_SIZE]; };
协议一般就是定义一个结构体。
服务器端:
#include<iostream> #include<map> #include<Winsock2.h> #include<thread> #include<time.h> #include<cstdio> #include<vector> using namespace std; #define MAX_CLIENT 10 #define MAX_BUF_SIZE 65535 #define UDP_SRV_PORT 2345 typedef pair<SOCKET, string> pii; int TcpClientCount = 0; char ServerTCPBuf[MAX_BUF_SIZE]; char ServerUDPBuf[MAX_BUF_SIZE]; char tmp[MAX_BUF_SIZE]; char ServerTCPTimeBuf[256]; //char getTime[256] = "GET CUR TIME"; //typedef pair<bool, string> pbs; //map<ULONG, pbs> islogin; struct TcpThreadParam { SOCKET sock; sockaddr_in addr; }; vector<pii> onlineUser; map<string, string> allUser; map<string, bool> isLogin; string realUser; //todo : 聊天 void TCPFun(TcpThreadParam *lpParam, DWORD threadId) { SOCKET TcpSocket = ((TcpThreadParam*)lpParam)->sock; SOCKADDR_IN TcpClientAddr = ((TcpThreadParam*)lpParam)->addr; sprintf(ServerTCPBuf, "%5d%s", UDP_SRV_PORT, "START"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send start error %d! ", threadId, WSAGetLastError()); } memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "1:新用户注册 2:用户登录 3:发消息聊天室 4:得到服务器时间 5:退出请输入exit再重新选择操作 请选择操作"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send start error %d! ", threadId, WSAGetLastError()); } int TCPBytesReceived; time_t CurSysTime; struct tm *tblock; string user; while(true) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0); if(TCPBytesReceived == 0 || TCPBytesReceived == SOCKET_ERROR) { break; } // printf("from %d.%d.%d.%d ", TcpClientAddr.sin_addr.S_un.S_un_b.s_b1, // TcpClientAddr.sin_addr.S_un.S_un_b.s_b2, TcpClientAddr.sin_addr.S_un.S_un_b.s_b3, // TcpClientAddr.sin_addr.S_un.S_un_b.s_b4); // ULONG ipULONG = TcpClientAddr.sin_addr.S_un.S_addr; int flag; flag = (USHORT)atoi(ServerTCPBuf); if(flag == 1) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "请输入用户名"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send user error %d! ", threadId, WSAGetLastError()); } memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0); user = (string)ServerTCPBuf; if(allUser.count(user)) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "该用户名已注册,请输入exit再重新选择操作!"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send other user error %d! ", threadId, WSAGetLastError()); } } else { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "请输入密码"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send password error %d! ", threadId, WSAGetLastError()); } memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0); string password = (string)ServerTCPBuf; memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "注册成功,请重新选择操作"); allUser[user] = password; if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send password error %d! ", threadId, WSAGetLastError()); } allUser[user] = password; } } else if(flag == 2) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "请输入用户名"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send user error %d! ", threadId, WSAGetLastError()); } memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0); string user = (string)ServerTCPBuf; if(!allUser.count(user)) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "没有该用户,请输入exit再重新选择操作"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send no user error %d! ", threadId, WSAGetLastError()); } } else { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "请输入密码"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send password error %d! ", threadId, WSAGetLastError()); } memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0); string password = (string) ServerTCPBuf; if(allUser[user] != password) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "exit"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send other password error %d! ", threadId, WSAGetLastError()); } } else { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "登录成功,请重新选择操作"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send error %d! ", threadId, WSAGetLastError()); } isLogin[user] = true; realUser = user; onlineUser.push_back(pii(TcpSocket, user)); } } } else if(flag == 3) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); sprintf(ServerTCPBuf, "%s", "请输入内容"); if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) { printf("thread %u send content error %d! ", threadId, WSAGetLastError()); } memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); while(true) { memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0); if(strlen(ServerTCPBuf) == 0) break; if(strcmp(ServerTCPBuf, "exit") == 0) { send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0); isLogin[user] = false; break; } else { printf("%s ", ServerTCPBuf); for(int i = 0; i < onlineUser.size(); i++) { if(onlineUser[i].first == TcpSocket || !isLogin[onlineUser[i].second]) continue; send(onlineUser[i].first, ServerTCPBuf, strlen(ServerTCPBuf), 0); } } } } else { CurSysTime = time(NULL); tblock = localtime(&CurSysTime); memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf)); strftime(ServerTCPBuf, sizeof(ServerTCPBuf), "%Y-%m-%d %H:%M:%S", tblock); // strcpy(ServerTCPTimeBuf, asctime(tblock)); memset(ServerTCPTimeBuf, 0, sizeof(ServerTCPTimeBuf)); sprintf(ServerTCPTimeBuf, "%s %s", ServerTCPBuf, "请重新选择操作"); if(send(TcpSocket, ServerTCPTimeBuf, strlen(ServerTCPTimeBuf), 0) == SOCKET_ERROR) { printf("thread %u send time error %d! ", threadId, WSAGetLastError()); } } } closesocket(TcpSocket); TcpClientCount--; } int ind; void UDPFun(DWORD threadID) { SOCKET UDPSrvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); char hostname[256]; gethostname(hostname, sizeof(hostname)); hostent *pHostent = gethostbyname(hostname); SOCKADDR_IN UDPSrvAddr; memset(&UDPSrvAddr, 0, sizeof(SOCKADDR_IN)); UDPSrvAddr.sin_family = AF_INET; UDPSrvAddr.sin_port = htons(UDP_SRV_PORT); UDPSrvAddr.sin_addr = *(in_addr*)pHostent->h_addr_list[ind]; bind(UDPSrvSocket, (sockaddr*)&UDPSrvAddr, sizeof(UDPSrvAddr)); while(true) { memset(ServerUDPBuf, 0, sizeof(ServerUDPBuf)); int iSockAddrLen = sizeof(sockaddr); SOCKADDR_IN UDPClientAddr; recvfrom(UDPSrvSocket, ServerUDPBuf, sizeof(ServerUDPBuf), 0, (sockaddr*)&UDPClientAddr, &iSockAddrLen); iSockAddrLen = sizeof(sockaddr); printf("ServerUDPBuf:%s ", ServerUDPBuf); sendto(UDPSrvSocket, ServerUDPBuf, strlen(ServerUDPBuf), 0, (sockaddr*)&UDPClientAddr, iSockAddrLen); } } WSADATA wsa; int main(int argc, char **argv) { WSAStartup(MAKEWORD(2, 2), &wsa); SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(ListenSocket == INVALID_SOCKET) { printf("TCP listen socket error %d! ", WSAGetLastError()); } char hostname[256]; gethostname(hostname, sizeof(hostname)); hostent *pHostent = gethostbyname(hostname); SOCKADDR_IN ListenAddr; ListenAddr.sin_family = AF_INET; ListenAddr.sin_port = htons((USHORT)atoi(argv[1])); for(DWORD i = 0; pHostent -> h_addr_list[i]; i++) { printf ("IP address %lu:%s ", i, inet_ntoa (*(struct in_addr*)pHostent->h_addr_list[i])); } scanf("%d", &ind); ListenAddr.sin_addr = *(in_addr*) pHostent -> h_addr_list[ind]; // ListenAddr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(ListenSocket, (sockaddr*)&ListenAddr, sizeof(ListenAddr)) == SOCKET_ERROR) { printf("TCP bind error %d! ", WSAGetLastError()); } if(listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) { printf("TCP listen error %d! ", WSAGetLastError()); } SOCKET TcpSocket; SOCKADDR_IN TcpClientAddr; DWORD dwUdpThreadId; thread udpt(UDPFun, dwUdpThreadId); udpt.detach(); while(true) { int iSockAddrLen = sizeof(sockaddr); TcpSocket = accept(ListenSocket, (sockaddr*)&TcpClientAddr, &iSockAddrLen); if(TcpSocket == INVALID_SOCKET) { printf("TcpSocket error %d! ", WSAGetLastError()); } TcpClientCount++; if(TcpClientCount >= MAX_CLIENT) { printf("> MAX_CLIENT "); closesocket(TcpSocket); continue; } TcpThreadParam Param; Param.sock = TcpSocket; Param.addr = TcpClientAddr; DWORD dwTcpThreadId; thread tcpt(TCPFun, &Param, dwTcpThreadId); tcpt.detach(); } closesocket(ListenSocket); WSACleanup(); return 0; }
客户端:
#include <Winsock2.h> #include <cstdio> #include <iostream> #include <thread> #define MAX_BUF_SIZE 65535 //接收发送缓冲区大小 using namespace std; char TCPClientBuf[MAX_BUF_SIZE]; char UDPClientBuf[MAX_BUF_SIZE]; char UDPRecvBuf[MAX_BUF_SIZE]; SOCKET TCPSocket, UDPSocket; char TCPSendBuf[MAX_BUF_SIZE]; char content[MAX_BUF_SIZE]; char getTime[256] = "GET CUR TIME"; USHORT ServerUDPPort; bool islogin = false; char user[10]; char password[20]; char realUser[10]; void sendMessage(SOCKET s) { while(true) { memset(content, 0, sizeof(content)); memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); scanf("%s", content); // printf("%s ", content); if(strcmp(content, "exit") != 0) { // printf("%s ", realUser); sprintf(TCPSendBuf, "%s:%s", realUser, content); if(send(s, TCPSendBuf, strlen(TCPSendBuf), 0) == SOCKET_ERROR) { printf("send Message error %d ", WSAGetLastError()); } } else { if(send(s, content, strlen(content), 0) == SOCKET_ERROR) { printf("send Message error %d ", WSAGetLastError()); } return; } } } int main(int argc, char * argv[]) { WSADATA wsaData; if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) { printf("Failed to load Winsock. "); return -1; } SOCKADDR_IN TCPServer, UDPServer; //填写要连接的服务器地址信息 TCPServer.sin_family = AF_INET; TCPServer.sin_port = htons((USHORT)atoi(argv[2])); //inet_addr()将命令行中输入的点分IP地址转换为二进制表示的网络字节序IP地址 TCPServer.sin_addr.s_addr = inet_addr(argv[1]); //建立客户端流式套接口 TCPSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(TCPSocket == INVALID_SOCKET) { printf("socket() Failed: %d ",WSAGetLastError()); return -1; } //请求与服务器端建立TCP连接 if(connect(TCPSocket,(sockaddr*)&TCPServer,sizeof(TCPServer)) == INVALID_SOCKET) { printf("connect() Failed: %d ", WSAGetLastError()); return -1; } int BytesReceived; BytesReceived = recv(TCPSocket, TCPClientBuf, sizeof(TCPClientBuf), 0); if(BytesReceived < 0) { printf("UDP port recv error %d! ", WSAGetLastError()); } char portnum[10]; memcpy(portnum, TCPClientBuf, 5); ServerUDPPort = (USHORT)atoi(portnum); printf("ServerUDPPort: %d ", ServerUDPPort); UDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); UDPServer.sin_family = AF_INET; UDPServer.sin_port = htons(ServerUDPPort); UDPServer.sin_addr.s_addr = inet_addr(argv[1]); // if(strcmp("START", TCPClientBuf + 5) != 0) { printf("%s ", TCPClientBuf + 5); return -1; } memset(TCPClientBuf, 0, sizeof(TCPClientBuf)); BytesReceived = recv(TCPSocket, TCPClientBuf, sizeof(TCPClientBuf), 0); printf("%s ", TCPClientBuf); int iSockAddrLen; while(true) { int UserChoice; // sudo:输入 scanf("%d", &UserChoice); if(UserChoice > 5) continue; memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); sprintf(TCPSendBuf, "%d", UserChoice); if(send(TCPSocket, TCPSendBuf, strlen(TCPSendBuf), 0) == SOCKET_ERROR) { printf("choice send error %d ", WSAGetLastError()); } int TCPBytesReceived; if(UserChoice == 1) { memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); scanf("%s", user); if(send(TCPSocket, user, strlen(user), 0) == SOCKET_ERROR) { printf("TCP send user error %d! ", WSAGetLastError()); } memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); scanf("%s", password); if(strcmp(password, "exit") != 0) { if(send(TCPSocket, password, strlen(password), 0) == SOCKET_ERROR) { printf("TCP send password error %d! ", WSAGetLastError()); } memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); } } else if(UserChoice == 2) { memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); scanf("%s", user); if(send(TCPSocket, user, strlen(user), 0) == SOCKET_ERROR) { printf("TCP send user error %d! ", WSAGetLastError()); } memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); scanf("%s", password); if(strcmp(password, "exit") != 0) { if(send(TCPSocket, password, strlen(password), 0) == SOCKET_ERROR) { printf("TCP send password error %d! ", WSAGetLastError()); } memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); if(strcmp(TCPSendBuf, "exit") == 0) { printf("密码错误 "); } else { strncpy(realUser, user, sizeof(user)); } // memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); // if(send(TCPSocket, TCPSendBuf, strlen(TCPSendBuf), 0) == SOCKET_ERROR) { // printf("TCP send user error %d! ", WSAGetLastError()); // } } } else if(UserChoice == 3) { memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); thread t(sendMessage, TCPSocket); t.detach(); while(true) { memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); if(strcmp(TCPSendBuf, "exit") == 0) break; printf("%s ", TCPSendBuf); } } else if(UserChoice == 4) { memset(TCPSendBuf, 0, sizeof(TCPSendBuf)); TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0); printf("%s ", TCPSendBuf); } else if(UserChoice == 5) { closesocket(TCPSocket); closesocket(UDPSocket); WSACleanup(); } } return 0; }