时间:2022-07-21 11:08:48 | 栏目:C代码 | 点击:次
TIPS:以下使用CMake项目进行开发。关于何为CMake,链接:https://www.jb51.net/article/247089.htm
简单聊天室效果展示
简单聊天室服务端源码(使用select模型)
// Server0327.cpp: 定义应用程序的入口点。 // #include "Server0327.h" #include <WinSock2.h> #include <vector> #pragma comment(lib,"ws2_32.lib") using namespace std; class TcpServer { public: bool Listen(const char* ip, int port) { //创建socket _serverSock = socket(AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == _serverSock) goto Exit; //绑定IP和端口号 SOCKADDR_IN addr; addr.sin_addr.s_addr = inet_addr(ip); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (INVALID_SOCKET == bind(_serverSock, (sockaddr*)&addr, sizeof(SOCKADDR_IN))) goto Exit; //监听端口 if (INVALID_SOCKET == listen(_serverSock, 255)) goto Exit; return true; Exit: closesocket(_serverSock); _serverSock = INVALID_SOCKET; return false; } void Update() { FD_SET reads; FD_ZERO(&reads); FD_SET(_serverSock, &reads); for (auto&& clientSock : _clientSocks) FD_SET(clientSock, &reads); int nRet = select(0, &reads, nullptr, nullptr, nullptr); if (nRet > 0) { if (FD_ISSET(_serverSock, &reads)) Accept(); else { for (int i = 0; i < _clientSocks.size(); i++) { if (FD_ISSET(_clientSocks[i], &reads)) { char buf[1024]{ 0 }; int nRecv = recv(_clientSocks[i], buf, 1024, 0); if (nRecv > 0) OnNetMsg(_clientSocks[i], buf, sizeof(buf)); if (nRecv <= 0) { closesocket(_clientSocks[i]); OnDisConnect(_clientSocks[i]); _clientSocks.erase(_clientSocks.begin() + i); continue; } } } } } } void Accept() { SOCKADDR_IN clientAddr; int clientAddrLen = sizeof(clientAddr); SOCKET clientSock = accept(_serverSock, (sockaddr*)&clientAddr, &clientAddrLen); if (INVALID_SOCKET != clientSock) { _clientSocks.push_back(clientSock); OnConnect(clientSock); } } void OnConnect(SOCKET clientSock) { printf("%d 客户端连接\n", clientSock); } int OnNetMsg(SOCKET clientSock, const char* buff, int len) { printf("%d == %s\n", clientSock, buff); for (auto&& clientSock : _clientSocks) send(clientSock, buff, len, 0); return len; } void OnDisConnect(SOCKET sock) { printf("%d==客户端断开连接\n", sock); } private: SOCKET _serverSock; vector<SOCKET> _clientSocks; }; int main() { WSADATA wsa; WSAStartup(MAKEWORD(2, 2), &wsa); TcpServer server; server.Listen("0.0.0.0", 7890); while (true) server.Update(); WSACleanup(); return 0; }
简单聊天室客户端源码(使用多线程)
// CMakeClient0331.cpp: 定义应用程序的入口点。 // #include "CMakeClient0331.h" #include<iostream> #include<WinSock2.h> #include<thread> #pragma comment(lib,"ws2_32.lib") int main() { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET clientSock = socket(AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == clientSock) { closesocket(clientSock); WSACleanup(); return 0; } SOCKADDR_IN serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); serverAddr.sin_port = htons(7890); if (INVALID_SOCKET == connect(clientSock, (sockaddr*)&serverAddr, sizeof(SOCKADDR_IN))) { closesocket(clientSock); WSACleanup(); return 0; } std::cout << "已连接服务端" << std::endl; std::thread t([&clientSock] { while (true) { char buf[1024]{ 0 }; int nRecvLen = recv(clientSock, buf, 1024, 0); if (nRecvLen <= 0) break; std::cout << "接收数据长度:" << nRecvLen << " 接受数据:" << buf << std::endl; } }); t.detach(); while (true) { char buf[1024]{ 0 }; std::cin >> buf; if (buf[0] == 'q')break; int nSendLen = send(clientSock, buf, sizeof(buf), 0); } closesocket(clientSock); WSACleanup(); return 0; }