select结构

MSDN上写到:
The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.
大意是:
select对一个包含socket的结构体进行判断,如果其中出现I/O事件,则返回。
这个包含socket套接字的结构体就是fd_set:
typedef struct fd_set {
u_int fd_count;
SOCKET fd_array[FD_SETSIZE]; } fd_set;
并提供了几个用用于维护这个结构体:
FD_ZERO  //清空结构体
FD_CLR   //从结构体清除成员
FD_SET  //添加SOCKET到结构体
FD_ISSET //判断套接字是否在结构体中

select函数接收一个fd_set结构体的指针,对其的成员进行判断,把有相应的socket事件留下,把没相应的给T掉,然后返回。
我们接下来只需要来个循环,对该结构体进行判断行了:

代码
//fdSaved是个包含所有套接字的结构体,每次判断都需要把fdSaved赋值给fdSocket,
//然后对fdSocket进行Select,这样才能对完整的套接字进行判断,否则越判断越少
  for (;;)
{
fdSocket
= fdSaved;
ret
= select(0,&fdSocket,NULL,NULL,NULL);

for (int i = 0 ; i < ret; i++)
{

//这里是判断s有无相应(s在外面初始化为一个socket服务端套接字)
if (fdSocket.fd_array[i] == s)
{
client
= ::accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);
printf(
" 接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));

// 向客户端发送数据
::send(client, szText, strlen(szText), 0);

// FD_SET(client,&fdClient);
FD_SET(client,&fdSaved);

}
else
{
char buff[256] = {0};
int n;
n
= recv(fdSocket.fd_array[i],buff,255,0);
if (n > 0)
{
buff[n]
= '\0';
}
else
{
//如果用户执行closesocket,就到这里,把用户T出去
closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],
&fdSaved);
continue;
}
printf(
"%d : %s\r\n",fdSocket.fd_array[i],buff);
ZeroMemory(buff,
256);

}
}

 

原理其实挺简单的,不过因为开始学习的时候,用了本不太好的书,导致好几天都没想明白,昨天复习了一下,写了个DOME代码,大部分就在上面了,可以接收客户端的请求并显示客户端输入的文本,,这玩意用着还是挺方便的,上面把关键的思想写清楚了,下面就不多扯了,OVER

 
posted @ 2010-06-03 11:14  飘啊飘  阅读(539)  评论(0编辑  收藏  举报