您的位置:首页 > 理论基础 > 计算机网络

WIN网络编程-select(I/O模型)

2009-12-21 21:30 429 查看
//////////////////////////////////////////////////////
// select.cpp文件

//select的优点是程序能够在单个线程内同时处理多个套接字连接,但是增加

//到fd_set结构的套接字是有限制的。winsock2.h定义为64,在包含winsock2.h

//之前重新定义它是可以的,但是最大不能超过1024,并且此值太大,影响服

//务器性能,因为select返回之前会检查这些集合中的套接字,并移除没有未

//决I/O操作的套接字。

//s为套接字

//FD_ZERO(*set)初始化set为空集合

//FD_CLR(s,*set)从set移除s

//FD_ISSET(s,*set)检查s是不是set的成员,如果是返回true

//FD_SET(s,*set)增加套接字到集合

#include "../common/initsock.h"
#include <stdio.h>

CInitSock theSock; //初始化Winsock库
int main()
{
USHORT nPort = 4567; //此服务器监听的端口号

// 创建监听套节字
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
// 绑定套节字到本地机器
if(::bind(sListen,(sockaddr*)&sin, sizeof(sin)) ==SOCKET_ERROR)
{
printf(" Failed bind()/n");
return -1;
}
// 进入监听模式
::listen(sListen, 5);

// select模型处理过程
// 1)初始化一个套节字集合fdSocket,添加监听套节字句柄到这个集合
fd_setfdSocket; // 所有可用套节字集合
FD_ZERO(&fdSocket);
FD_SET(sListen, &fdSocket);
while(TRUE)
{
//2)将fdSocket集合的一个拷贝fdRead传递给select函数,
//当有事件发生时,select函数移除fdRead集合中没有未决I/O操作的套节字句柄,然后返回。
fd_set fdRead = fdSocket;
int nRet = ::select(0,&fdRead, NULL, NULL, NULL);
if(nRet >0)
{
//3)通过将原来fdSocket集合与select处理过的fdRead集合比较,
//确定都有哪些套节字有未决I/O,并进一步处理这些I/O。
for(int i=0;i<(int)fdSocket.fd_count; i++)
{
if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
{
if(fdSocket.fd_array[i]== sListen) //(1)监听套节字接收到新连接
{
if(fdSocket.fd_count< FD_SETSIZE)
{
sockaddr_inaddrRemote;
intnAddrLen = sizeof(addrRemote);
SOCKETsNew = ::accept(sListen, (SOCKADDR*)&addrRemote,&nAddrLen);
FD_SET(sNew,&fdSocket);
printf("接收到连接(%s)/n",::inet_ntoa(addrRemote.sin_addr));
}
else
{
printf("Too much connections! /n");
continue;
}
}
else
{
charszText[256];
intnRecv = ::recv(fdSocket.fd_array[i], szText, strlen(szText),0);
if(nRecv>0) //(2)可读
{
szText[nRecv]= '/0';
printf("接收到数据:%s/n", szText);
}
else //(3)连接关闭、重启或者中断
{
::closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],&fdSocket);
}
}
}
}
}
else
{
printf("Failed select() /n");
break;
}
}
return 0;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: