选择模型数组
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 }