本文主要介绍了C++ select模型简单聊天室的实现示例,使用CMake项目进行开发,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
TIPS:以下使用CMake项目进行开发。关于何为CMake,链接:
简单聊天室效果展示
简单聊天室服务端源码(使用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++ select模型简单聊天室的实现示例
猜你喜欢
- ubuntu下C/C++获取剩余内存 2023-09-18
- c++ const 成员函数,返回一个 const 指针.但是返回的指针是什么类型的 const? 2022-10-11
- C++ 数据结构超详细讲解顺序表 2023-03-25
- 我应该为我的项目使用相对包含路径,还是将包含目录放在包含路径上? 2022-10-30
- Qt计时器使用方法详解 2023-05-30
- C语言详解float类型在内存中的存储方式 2023-03-27
- Easyx实现扫雷游戏 2023-02-06
- C语言手把手带你掌握带头双向循环链表 2023-04-03
- 详解C语言中sizeof如何在自定义函数中正常工作 2023-04-09
- C语言qsort()函数的使用方法详解 2023-04-26