选择模型2

选择模型数组

fd_set结构能够把多个套接字连在一块儿,造成一个套接字集合服务器

typedef struct fd_set{ u_int fd_count;//下面数组的大小
SOCKET fd_array[FD_SETSIZE];//套接字句柄数组
}fd_set;

网络事件:网络

readfds集合:数据可读,链接关闭,重启或者中断socket

writefds集合:数据能发送函数

exceptfds集合:OOB数据可读spa

设置超时:code

若是为null为无限阻塞,知道有网络事件发生blog

typedef struct timeval{ long tv_sec;//指示等待多少秒
long tv_usec;//指示等待多少毫秒
}timeval;

应用举例事件

1 初始化fdSocket集合,添加监听套接字句柄it

2 将fdSocket集合拷贝fRead传递给select函数,当有事件发生的时候,select函数移除fRead中没有未决IO操做的句柄,而后返回

3 比较原来的fdSocket集合,与select处理过的fdRead集合,肯定哪些套接字有未决IO并处理这些IO

4 回到2进行选择

 1 CInitSock theSock;//初始化winsock库
 2 int main()  3 {  4     USHORT nPort=4567;//此服务器监听的端口号  5     //建立监听套接字
 6     SOCKET sListen=::listen(AF_INET,SOCK_STREAM,IPPROTO_TCP);  7  sockaddr_in sin;  8     sin.sin_family = AF_INET;  9     sin.sin_port = htons(nPort); 10     sin.sin_addr.S_un.S_addr = INADDR_ANY; 11     //绑定套接字到本地机器
12     if(::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR) 13  { 14         printf("Failed bind()!\n"); 15         return 0; 16  } 17     //进入监听模式
18     ::listen(sListen,5); 19     
20     //select模型处理过程
21     ////////////////////////////////////////////////////////////////////////////
22     // 1 初始化fdSocket集合,添加监听套接字句柄
23     fd_set fdSocket;//全部可用套接字集合
24     FD_ZERO(&fdSocket); 25     FD_SET(sListen,&fdSocket); 26     while(TRUE) 27  { 28         //////////////////////////////////////////////////////////////////////// 29         //2 将fdSocket集合拷贝fRead传递给select函数,当有事件发生的时候,select函数移除fRead中没有未决IO操做的句柄,而后返回
30         fd_set fdRead = fdSocket; 31         int nRet = ::select(0,&fdRead,NULL,NULL,NULL); 32         if(nRet>0) 33  { 34             ///////////////////////////////////////////////////////////////////
35             // 3 比较原来的fdSocket集合,与select处理过的fdRead集合,肯定哪些套接字有未决IO并处理这些IO
36             for(int i=0;i<(int)fdSocket.fd_count;i++) 37  { 38                 if(FD_ISSET(fdSocket.fd_array[i],&fdRead)) 39  { 40                     if(fdSocket.fd_array[i]==sListen)// 1 监听套接字链接新链接
41  { 42  sockaddr_in addrRemote; 43                         int nAddrLen = sizeof(addrRemote); 44                         SOCKET sNew = ::accept(sListen,(SOCKADDR*)&addrRemote,&nAddrLen); 45                         FD_SET(sNew,&fdSocket); 46                         printf("接收到链接(%s)\n",::inet_ntoa(addrRemote.sin_addr)); 47  } 48                     else
49  { 50                         printf("Too much connections!\n"); 51                         continue; 52  } 53  } 54                 else
55  { 56                     char szText[256]; 57                     int nRecv = ::recv(fdSocket.fd_array[i],szText,strlen(szText),0); 58                     if(nRecv > 0)//可读
59  { 60                         szText[nRecv] = '\0'; 61                         printf("接收到数据:%s\n",szText); 62  } 63                     else//链接关闭或者重启
64  { 65  ::closesocket(fdSocket.fd_array[i]); 66                         FD_CLR(fdSocket.fd_array[i],&fdSocket); 67  } 68  } 69  } 70  } 71         else
72  { 73             printf("Failed select()!\n"); 74             break; 75  } 76  } 77     return 0; 78 }
相关文章
相关标签/搜索