网络编程SELECT模型

这篇博客介绍了一个在Windows环境下用C++编写的TCP服务器程序,利用WSAStartup和WSAData初始化网络环境,然后创建并监听指定IP和端口的套接字。通过Select模型处理客户端连接和数据收发,实现服务端与客户端的通信。当接收到客户端连接请求时,服务器会将其加入读集合,并持续监听和接收数据,直到连接断开。
#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值