I/O模型之select模型

代码:

void main()
{
	CInitSock initSock;
	USHORT nPort = 9999; //监听的端口
	SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sListen == INVALID_SOCKET)
	{
		printf("socket error...");
		return;
	}
	sockaddr_in servAddr = {0};
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = ::htons(nPort);
	servAddr.sin_addr.S_un.S_addr = INADDR_ANY; 
	if (SOCKET_ERROR == ::bind(sListen, (sockaddr*)&servAddr, sizeof(servAddr)))
	{
		int nError = ::GetLastError();
		printf("connect error..");
		return;
	}
	::listen(sListen, 5);

	
	//select模型处理过程
	//1.初始化套接字集合,添加监听socket到这个集合
	fd_set	fdSocket;
	FD_ZERO(&fdSocket);
	FD_SET(sListen, &fdSocket);
	while (TRUE)
	{
		//2. 将集合的一个拷贝传递给select函数
		//当有事件发生时,select移除未决的socket,然后返回   就是说select返回时 集合的中socket就是发生事件的socket
		fd_set fdRead = fdSocket;
		int nRet = ::select(0, &fdRead, NULL, NULL, NULL);
		if (nRet > 0)
		{
			//通过比较原来的fdSocket集合与经过处理的fdRead集合
			for (UINT i=0;i<fdSocket.fd_count;i++)
			{
				if (FD_ISSET(fdSocket.fd_array[i], &fdRead)) //就是这个触发了
				{
					if (fdSocket.fd_array[i] == sListen) //监听套接字接收到新连接  为神马分两种情况:因为触发Read集合的情况有两种:有连接来了或数据可读了....
					{
						//
						if (fdSocket.fd_count < FD_SETSIZE) //FD_SETSIZE=64
						{
							sockaddr_in addrRemote = {0};
							int nAddrLen = sizeof(addrRemote);
							SOCKET sNew = ::accept(sListen, (sockaddr*)&addrRemote, &nAddrLen);
							FD_SET(sNew, &fdSocket);
						}
						else	
						{
							printf("too many connection...error");
							continue;
						}
					}
					else  //有可读的
					{
						char szContent[256]={0};
						int nRecv = ::recv(fdSocket.fd_array[i], szContent, sizeof(szContent), 0);
						if (nRecv > 0)
						{
							szContent[nRecv] = '\0';
							printf("recv data:%s", szContent);
						}
						else //没读到数据
						{
							::closesocket(fdSocket.fd_array[i]);
							FD_CLR(fdSocket.fd_array[i], &fdSocket);
						}
					}
				}
			}
		}
		else
		{
			printf("nRet litter 0, error...");
			return;
		}
	}
	::closesocket(sListen); //与socket配对写
	printf("*******************************");
	getchar();
}


效果图:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值