C++?select模型簡(jiǎn)單聊天室的實(shí)現(xiàn)示例
TIPS:以下使用CMake項(xiàng)目進(jìn)行開(kāi)發(fā)。關(guān)于何為CMake,鏈接:http://www.dbjr.com.cn/article/247089.htm
簡(jiǎn)單聊天室效果展示
簡(jiǎn)單聊天室服務(wù)端源碼(使用select模型)
// Server0327.cpp: 定義應(yīng)用程序的入口點(diǎn)。 // #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) ?? ?{ ?? ??? ?//創(chuàng)建socket ?? ??? ?_serverSock = socket(AF_INET, SOCK_STREAM, 0); ?? ??? ?if (INVALID_SOCKET == _serverSock) ?? ??? ??? ?goto Exit; ?? ??? ?//綁定IP和端口號(hào) ?? ??? ?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; ?? ??? ?//監(jiān)聽(tīng)端口 ?? ??? ?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==客戶端斷開(kāi)連接\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; }
簡(jiǎn)單聊天室客戶端源碼(使用多線程)
// CMakeClient0331.cpp: 定義應(yīng)用程序的入口點(diǎn)。 // #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 << "已連接服務(wù)端" << 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 << "接收數(shù)據(jù)長(zhǎng)度:" << nRecvLen << " 接受數(shù)據(jù):" << 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; }
到此這篇關(guān)于C++ select模型簡(jiǎn)單聊天室的文章就介紹到這了,更多相關(guān)C++ select模型簡(jiǎn)單聊天室內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++數(shù)據(jù)結(jié)構(gòu)之單鏈表的實(shí)現(xiàn)
線性表的鏈?zhǔn)酱鎯?chǔ)又稱為單鏈表,它是指通過(guò)一組任意的存儲(chǔ)單元來(lái)存儲(chǔ)線性表中的數(shù)據(jù)元素。本文將用C++實(shí)現(xiàn)單鏈表,需要的可以參考一下2022-05-05配置CLion管理Qt項(xiàng)目國(guó)際化支持的方法
這篇文章主要介紹了配置CLion管理Qt項(xiàng)目國(guó)際化支持的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04C++11智能指針中的 unique_ptr實(shí)例詳解
unique是獨(dú)特的、唯一的意思,故名思議,unique_ptr可以“獨(dú)占”地?fù)碛兴赶虻膶?duì)象,它提供一種嚴(yán)格意義上的所有權(quán)。這篇文章主要介紹了C++11智能指針中的 unique_ptr實(shí)例詳解,需要的朋友可以參考下2020-06-06