±¾ÎÄÖ÷Òª·ÖÎöÁ˼¸ÖÖSocket±à³ÌµÄģʽ¡£Ö÷Òª°üÀ¨»ù±¾µÄ×èÈûSocket¡¢·Ç×èÈûSocket¡¢I/O¶à·¸´Óá£ÆäÖУ¬×èÈûºÍ·Ç×èÈûÊÇÏà¶ÔÓÚÌ×½Ó×ÖÀ´ËµµÄ£¬¶øÆäËûµÄģʽ±¾ÖÊÉÏÀ´ËµÊÇ»ùÓÚSocketµÄ²¢·¢Ä£Ê½¡£I/O¶à·¸´ÓÃÓÖÖ÷Òª·ÖÎöÁË·ÖÎölinuxºÍwindowsϵij£ÓÃÄ£ÐÍ¡£×îºó£¬±È½ÏÕ⼸ÖÖSocket±à³ÌģʽµÄÓÅȱµã£¬²¢ÌÖÂÛ¶àÏß³ÌÓëSocketµÄ×éºÏʹÓúͷþÎñÆ÷¿ª·¢µÄ³£ÓÃģʽ¡£
×èÈûģʽ×èÈûģʽÊÇ×î»ù±¾µÄSocket±à³Ìģʽ£¬ÔÚ¸÷ÖÖ¹ØÓÚÍøÂç±à³ÌµÄÊé¼®Öж¼ÊÇÈëÃŵÄÀý×Ó¡£¾ÍÏñÆäÃûËù˵£¬×èÈûģʽµÄSocket»á×èÈûµ±Ç°µÄỊ̈߳¬Ö±µ½½á¹û·µ»Ø£¬·ñÔò»áÒ»Ö±µÈ´ý¡£
·Ç×èÈûģʽ·Ç×èÈûģʽÊÇÏà¶Ô×èÈûģʽÀ´Ëµ£¬Socket²¢²»»á×èÈûµ±Ç°Ị̈߳¬·Ç×èÈûģʽ²»»áµÈµ½½á¹û·µ»Ø£¬¶ø»áÁ¢¼´ÔËÐÐÏÂÈ¥¡£
//ÉèÖÃÌ×½Ó×ÖΪ·Ç×èÈûģʽ fcntl( sockfd, F_SETFL, O_NONBLOCK); //O_NONBLOCK±êÖ¾ÉèÖ÷Ç×èÈûģʽÕâÀïÐèҪעÒ⣬×èÈû/·Ç×èÈû¡¢Í¬²½/Ò첽֮ǰµÄÇø±ð¡£ÔÚ±¾ÖÊÉÏËüÃÇÊDz»Í¬µÄ¡£Í¬²½ºÍÒì²½ÊÇÏà¶Ô²Ù×÷½á¹ûÀ´Ëµ£¬»á²»»áµÈ´ý½á¹û½á¹û·µ»Ø¡£¶ø×èÈûºÍ·Ç×èÈûÊÇÏà¶ÔÏß³ÌÊÇ·ñ±»×èÈûÀ´ËµµÄ¡£Æäʵ£¬ÕâÁ½Õß´æÔÚ±¾ÖʵÄÇø±ð£¬ËüÃǵÄÐÞÊζÔÏóÊDz»Í¬µÄ¡£×èÈûºÍ·Ç×èÈûÊÇÖ¸½ø³Ì·ÃÎʵÄÊý¾ÝÈç¹ûÉÐδ¾ÍÐ÷£¬½ø³ÌÊÇ·ñÐèÒªµÈ´ý£¬¼òµ¥ËµÕâÏ൱ÓÚº¯ÊýÄÚ²¿µÄʵÏÖÇø±ð£¬Ò²¾ÍÊÇδ¾ÍÐ÷ʱÊÇÖ±½Ó·µ»Ø»¹Êǵȴý¾ÍÐ÷¡£¶øͬ²½ºÍÒì²½ÊÇÖ¸·ÃÎÊÊý¾ÝµÄ»úÖÆ,ͬ²½Ò»°ãÖ¸Ö÷¶¯ÇëÇ󲢵ȴýI/O²Ù×÷Íê±ÏµÄ·½Ê½,µ±Êý¾Ý¾ÍÐ÷ºóÔÚ¶ÁдµÄʱºò±ØÐë×èÈû,Òì²½ÔòÖ¸Ö÷¶¯ÇëÇóÊý¾Ýºó±ã¿ÉÒÔ¼ÌÐø´¦ÀíÆäËüÈÎÎñ,ËæºóµÈ´ýI/O,²Ù×÷Íê±ÏµÄ֪ͨ,Õâ¿ÉÒÔʹ½ø³ÌÔÚÊý¾Ý¶ÁдʱҲ²»×èÈû¡£ÒòΪÁ½ÕßÔÚ±íÏÖÉϾ³£Ïàͬ£¬ËùÒÔ¾³£±»»ìÏý¡£
I/O¶à·¸´ÓÃI/O¶à·¸´ÓÃÊÇÒ»ÖÖ²¢·¢·þÎñÆ÷¿ª·¢¼¼Êõ(´¦Àí¶à¸ö¿Í»§¶ËµÄÁ¬½Ó)¡£Í¨¹ý¸Ã¼¼Êõ£¬ÏµÍ³Äں˻º³åI/OÊý¾Ý£¬µ±Ä³¸öI/O×¼±¸ºÃºó£¬ÏµÍ³Í¨ÖªÓ¦ÓóÌÐò¸ÃI/O¿É¶Á»ò¿Éд£¬ÕâÑùÓ¦ÓóÌÐò¿ÉÒÔÂíÉÏÍê³ÉÏàÓ¦µÄI/O²Ù×÷£¬¶ø²»ÐèÒªµÈ´ýϵͳÍê³ÉÏàÓ¦I/O²Ù×÷£¬´Ó¶øÓ¦ÓóÌÐò²»±ØÒòµÈ´ýI/O²Ù×÷¶ø×èÈû¡£
ÔÚlinuxÏÂÖ÷ÒªÓÐselect¡¢poll¡¢epollÈýÖÖÄ£ÐÍ£¬ÔÚfreeBSDÏÂÔòÓÐkqueue£¬windwosÏÂselect¡¢Ê¼þÑ¡ÔñÄ£ÐÍ¡¢ÖصþI/OºÍÍê³É¶Ë¿ÚµÈ¡£
select±¾ÖÊÊÇͨ¹ýÉèÖûò¼ì²é´æ·Åfd±ê־λµÄÊý¾Ý½á¹¹À´½øÐÐÏÂÒ»²½µÄ´¦Àí¡£selectÊDzÉÓÃÂÖѯfd¼¯ºÏÀ´½øÐд¦ÀíµÄ¡£
//selectÏà¹Øº¯Êý int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,const struct timeval *timeout) //·µ»ØÖµ£º¾ÍÐ÷ÃèÊö·ûµÄÊýÄ¿£¬³¬Ê±·µ»Ø0£¬³ö´í·µ»Ø-1 void FD_ZERO(fd_set *fdset); //Çå¿Õ¼¯ºÏ void FD_SET(int fd, fd_set *fdset); //½«Ò»¸ö¸ø¶¨µÄÎļþÃèÊö·û¼ÓÈ뼯ºÏÖ®ÖÐ void FD_CLR(int fd, fd_set *fdset); //½«Ò»¸ö¸ø¶¨µÄÎļþÃèÊö·û´Ó¼¯ºÏÖÐɾ³ý int FD_ISSET(int fd, fd_set *fdset); // ¼ì²é¼¯ºÏÖÐÖ¸¶¨µÄÎļþÃèÊö·ûÊÇ·ñ¿ÉÒÔ¶Á䵫ÊÇ£¬select´æÔÚÒ»¶¨µÄȱÏÝ¡£µ¥¸ö½ø³Ì¿É¼àÊÓµÄfdÊýÁ¿±»ÏÞÖÆ£¬linuxÏÂÒ»°ãΪ1024¡£ËäÈ»ÊÇ¿ÉÒÔÐ޸ĵģ¬µ«ÊÇ×ÜÊÇÓÐÏÞÖƵġ£ÔÚÿ´Îµ÷ÓÃselectʱ£¬¶¼ÐèÒª°Ñfd¼¯ºÏ´ÓÓû§Ì¬¿½±´µ½ÄÚºË̬£¬¶øÇÒÐèҪѻ·Õû¸öfd¼¯ºÏ£¬Õâ¸ö¿ªÏúºÜ¶àʱºòÊDZȽϴóµÄ¡£
pollpollµÄʵÏÖºÍselect·Ç³£ÏàËÆ£¬±¾ÖÊÉÏÊÇÏàͬ£¬Ö»ÊÇÃèÊöfd¼¯ºÏµÄ·½Ê½²»Í¬¡£pollÊÇ»ùÓÚÁ´±íÀ´´æ´¢µÄ¡£ÕâËäȻûÓÐÁË×î´óÁ¬½ÓÊýµÄÏÞÖÆ£¬µ«ÊÇÈÔÈ»»¹ÓÐfd¼¯ºÏ¿½±´ºÍÑ»·´øÀ´µÄ¿ªÏú¡£¶øÇÒpoll»¹ÓÐÒ»¸öÌصãÊÇˮƽ´¥·¢£¬ÄÚºË֪ͨÁËfdºó£¬Ã»Óб»´¦Àí£¬ÄÇôÄں˾ͻ᲻¶ÏµÄ֪ͨ£¬Ö±µ½±»´¦Àí¡£
//pollÏà¹Øº¯Êý int poll(struct pollfd *fdarray, unsigned long nfds, int timeout); epollepollÊǶÔselectºÍpollµÄ¸Ä½ø¡£Ïà½ÏÓÚpoll£¬epollʹÓá°Ê¼þ¡±µÄ¾ÍÐ÷֪ͨ£¬Í¨¹ýepoll_ctl×¢²áfd£¬Ò»µ©¸Ãfd¾ÍÐ÷£¬Äں˾ͻá²ÉÓÃÀàËÆcallbackµÄ»Øµ÷»úÖÆÀ´¼¤»î¸Ãfd£¬°Ñ¾ÍÐ÷fd·ÅÈë¾ÍÐ÷Á´±íÖУ¬²¢»½ÐÑÔÚepoll_waitÖнøÈë˯ÃߵĽø³Ì£¬ÕâÑù²»ÔÚÐèÒªÂÖѯ£¬ÅжÏfdºÏ¼ÆºÏ¼¯ÊÇ·ñΪ¿Õ¡£¶øÇÒepoll²»½öÖ§³Öˮƽ´¥·¢£¬»¹Ö§³Ö±ßÔµ´¥·¢¡£±ßÔµ´¥·¢ÊÇÖ¸ÄÚºË֪ͨfdÖ®ºó£¬²»¹Ü´¦²»´¦Àí¶¼²»ÔÚ֪ͨÁË¡£ÔÚ´æ´¢fdµÄ¼¯ºÏÉÏ£¬epollÒ²²ÉÓÃÁ˸üΪÓÅÐãµÄmmap£¬¶øÇһᱣ֤fd¼¯ºÏ¿½±´Ö»»á·¢ÉúÒ»´Î¡£
//epollÏà¹Øº¯Êý int epoll_create(int size); //¾ä±úµÄ´´½¨ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); //ʼþ×¢²á int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout); //µÈ´ýʼþµÄ·¢Éú WindowsÉϵÄI/O¸´ÓÃÄ£ÐÍ Ê¼þÑ¡ÔñÄ£ÐÍʼþÑ¡ÔñÄ£ÐÍÊÇ»ùÓÚÏûÏ¢µÄ¡£ËüÔÊÐí³ÌÐòͨ¹ýSocket£¬½ÓÊÕÒÔʼþΪ»ù´¡µÄÍøÂçʼþ֪ͨ¡£
//ʼþÑ¡ÔñÄ£ÐÍÏà¹Øº¯Êý WSAEVENT WSACreatEvent(void); //´´½¨Ê¼þ¶ÔÏó int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, long lNetworkEvents); //¹ØÁªÊ¼þ ÖصþI/OÄ£ÐÍÖصþI/OÄ£ÐÍÊÇÒì²½I/OÄ£ÐÍ¡£ÖصþÄ£Ð͵ĺËÐÄÊÇÒ»¸öÖصþÊý¾Ý½á¹¹¡£ÖصþÄ£ÐÍÊÇÈÃÓ¦ÓóÌÐòʹÓÃÖصþÊý¾Ý½á¹¹(WSAOVERLAPPED)£¬Ò»´ÎͶµÝÒ»¸ö»ò¶à¸öWinsock I/OÇëÇó¡£ÈôÏëÒÔÖصþ·½Ê½Ê¹ÓÃÎļþ£¬±ØÐëÓÃFILE_FLAG_OVERLAPPED ±êÖ¾´ò¿ªËü¡£µ±I/O²Ù×÷Íê³Éºó£¬ÏµÍ³Í¨ÖªÓ¦ÓóÌÐò¡£ÀûÓÃÖصþI/OÄ£ÐÍ£¬Ó¦ÓóÌÐòÔÚµ÷ÓÃI/Oº¯ÊýÖ®ºó£¬Ö»ÐèÒªµÈ´ýI/O²Ù×÷Íê³ÉµÄÏûÏ¢¼´¿É¡£
HANDLE hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);¡¡ Íê³É¶Ë¿ÚÄ£ÐÍ(IOCP)IOCPÍê³É¶Ë¿ÚÊÇÄ¿Ç°WindowsÏÂÐÔÄÜ×îºÃµÄI/OÄ£ÐÍ£¬µ±È»Ò²ÊÇ×Ôӵġ£¼òµ¥µÄ˵£¬IOCP ÊÇÒ»ÖÖ¸ßÐÔÄܵÄI/OÄ£ÐÍ£¬ÊÇÒ»ÖÖÓ¦ÓóÌÐòʹÓÃÏ̳߳ش¦ÀíÒì²½I/OÇëÇóµÄ»úÖÆ¡£IOCP½«ËùÓÐÓû§µÄÇëÇó¶¼Í¶µÝµ½Ò»¸öÏûÏ¢¶ÓÁÐÖÐÈ¥£¬È»ºóÏ̳߳ØÖеÄÏß³ÌÖðÒ»´ÓÏûÏ¢¶ÓÁÐÖÐȥȡ³öÏûÏ¢²¢¼ÓÒÔ´¦Àí£¬¾Í¿ÉÒÔ±ÜÃâÕë¶Ôÿһ¸öI/OÇëÇ󶼿ªÏ̡߳£²»½ö¼õÉÙÁËÏ̵߳Ä×ÊÔ´£¬Ò²Ìá¸ßÁËÏ̵߳ÄÀûÓÃÂÊ¡£
//IOCP¼òµ¥Á÷³Ì //´´½¨Íê³É¶Ë¿Ú Port port = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, fixedThreadCount()); //½«Socket¹ØÁªµ½IOCP CreateIoCompletionPort((HANDLE )m_sockClient,m_hIocp, (ULONG_PTR )m_sockClient, 0); //ͶµÝAcceptExÇëÇó LPFN_ACCEPTEX m_lpfnAcceptEx; // AcceptExº¯ÊýÖ¸Õë GUID GuidAcceptEx = WSAID_ACCEPTEX; // GUID£¬Õâ¸öÊÇʶ±ðAcceptExº¯Êý±ØÐëµÄ DWORD dwBytes = 0; WSAIoctl( m_pListenContext->m_Socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &m_lpfnAcceptEx, sizeof(m_lpfnAcceptEx), &dwBytes, NULL, NULL); //ʹÓÃGetQueuedCompletionStatus()¼à¿ØÍê³É¶Ë¿Ú void *lpContext = NULL; OVERLAPPED *pOverlapped = NULL; DWORD dwBytesTransfered = 0; BOOL bReturn = GetQueuedCompletionStatus( pIOCPModel->m_hIOCompletionPort, &dwBytesTransfered, (LPDWORD)&lpContext, &pOverlapped, INFINITE ); //ÊÕµ½Í¨Öª int nBytesRecv = WSARecv(pIoContext->m_Socket, pIoContext ->p_wbuf, 1, &dwBytes, 0, pIoContext->p_ol, NULL); Ï̵߳ÄʹÓÃ
¡¡