選擇模型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 }
相關文章
相關標籤/搜索