C++ select模型简单聊天室的实现示例

Glenna ·
更新时间:2024-09-20
· 48 次阅读

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; }

到此这篇关于C++ select模型简单聊天室的文章就介绍到这了,更多相关C++ select模型简单聊天室内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网!



c+ 示例 聊天室 C++ select

需要 登录 后方可回复, 如果你还没有账号请 注册新账号