#include <windows.h>
#include <iostream>
#pragma comment(lib,"WS2_32.lib")
int main()
{
WSAData wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET sockSvr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in svrAddr;
memset(&svrAddr, 0, sizeof(svrAddr));
svrAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
svrAddr.sin_family = AF_INET;
svrAddr.sin_port = htons(8000);
if (bind(sockSvr, (struct sockaddr *)&svrAddr, sizeof(svrAddr)) != 0)
{
std::cout << "bind error" << GetLastError();
return -1;
}
listen(sockSvr, 1);
//开始使用Select模型了
fd_set readSet; //定义一个读的集合
FD_ZERO(&readSet);
FD_SET(sockSvr, &readSet);
while (true)
{
fd_set tmpSet; //定义一个读的集合
FD_ZERO(&tmpSet);
tmpSet = readSet;
//利用SELECT选择出集合中可以读写的套接字
//最后一个参数,为空时一直等待,阻塞,如果设置时间,则等待时间超时
timeval tv = { 0,1000 };
int ret = select(0, &tmpSet, NULL, NULL, NULL);
if (ret == SOCKET_ERROR)
{
continue;
}
for (int i = 0; i < tmpSet.fd_count; ++i)
{
SOCKET s = tmpSet.fd_array[i];
//接收到客户端的连接,如果有变化的是服务端SOCKET的话
if (s == sockSvr)
{
SOCKET c = accept(s, NULL, NULL);
//最大为64,如果要改变,给size赋值 ,最大最好不要超过1024
if (readSet.fd_count < FD_SETSIZE)
{
FD_SET(c, &readSet);
std::cout << "连接成功" << c << std::endl;
}
}
else
{
//接收客户端数据
char buff[1024] = { 0 };
ret = recv(s, buff, 1024, 0);
if (ret == SOCKET_ERROR || ret == 0)
{
closesocket(s);
FD_CLR(s, &readSet);
std::cout << s << "断开连接" << std::endl;
}
else
{
std::cout << buff << std::endl;
}
}
}
}
closesocket(sockSvr);
return true;
}
网络编程SELECT模型
最新推荐文章于 2025-04-28 16:40:31 发布
这篇博客介绍了一个在Windows环境下用C++编写的TCP服务器程序,利用WSAStartup和WSAData初始化网络环境,然后创建并监听指定IP和端口的套接字。通过Select模型处理客户端连接和数据收发,实现服务端与客户端的通信。当接收到客户端连接请求时,服务器会将其加入读集合,并持续监听和接收数据,直到连接断开。

5593

被折叠的 条评论
为什么被折叠?



