异步通知I/O模型(Windows)
# include <string.h>
# include <stdio.h>
# include <WinSock2.h>
# define BUF_SIZE 100
void CompressSockets ( SOCKET hSockArr[ ] , int idx, int total) ;
void CompressEvent ( WSAEVENT hEventArr[ ] , int idx, int total) ;
char msg[ BUF_SIZE] ;
int main ( int argc, char * argv[ ] )
{ WSADATA wsaData; if ( WSAStartup ( MAKEWORD ( 2 , 2 ) , & wsaData) != 0 ) { printf ( "WSAStartup error!\n" ) ; return - 1 ; } SOCKET hServSock, hClentSock; SOCKADDR_IN servAdr, clntAdr; SOCKET hSockArr[ WSA_MAXIMUM_WAIT_EVENTS] ; WSAEVENT hEventArr[ WSA_MAXIMUM_WAIT_EVENTS] ; int numOfClntSock = 0 ; WSAEVENT newEvent; hServSock = socket ( PF_INET, SOCK_STREAM, 0 ) ; memset ( & servAdr, 0 , sizeof ( servAdr) ) ; servAdr. sin_family = AF_INET; servAdr. sin_addr. s_addr = htonl ( INADDR_ANY) ; servAdr. sin_port = ntohs ( atoi ( argv[ 1 ] ) ) ; if ( bind ( hServSock, ( SOCKADDR* ) & servAdr, sizeof ( servAdr) ) == SOCKET_ERROR) { printf ( "bind error!\n" ) ; return - 2 ; } if ( listen ( hServSock, 5 ) == SOCKET_ERROR) { printf ( "listen error!\n" ) ; return - 3 ; } newEvent = WSACreateEvent ( ) ; if ( WSAEventSelect ( hServSock, newEvent, FD_ACCEPT) == SOCKET_ERROR) { printf ( "listen error!\n" ) ; return - 4 ; } hSockArr[ numOfClntSock] = hServSock; hEventArr[ numOfClntSock] = newEvent; numOfClntSock++ ; while ( 1 ) { int posInfo, StartIdx; posInfo = WSAWaitForMultipleEvents ( numOfClntSock, hEventArr, FALSE, WSA_INFINITE, FALSE) ; StartIdx = posInfo - WSA_WAIT_EVENT_0; for ( int i = StartIdx; i < numOfClntSock; i++ ) { int sigEventIdx = WSAWaitForMultipleEvents ( 1 , & hEventArr[ i] , TRUE, 0 , FALSE) ; if ( sigEventIdx == WSA_WAIT_FAILED || sigEventIdx == WSA_WAIT_TIMEOUT) { continue ; } else { WSANETWORKEVENTS netEvents; sigEventIdx = i; WSAEnumNetworkEvents ( hSockArr[ sigEventIdx] , hEventArr[ sigEventIdx] , & netEvents) ; if ( netEvents. lNetworkEvents & FD_ACCEPT) { if ( netEvents. iErrorCode[ FD_ACCEPT_BIT] ) { printf ( "Accept Error!\n" ) ; return - 5 ; } int clntAdrLen = sizeof ( clntAdr) ; hClentSock = accept ( hSockArr[ sigEventIdx] , ( SOCKADDR* ) & clntAdr, & clntAdrLen) ; newEvent = WSACreateEvent ( ) ; WSAEventSelect ( hClentSock, newEvent, FD_READ | FD_CLOSE) ; hEventArr[ numOfClntSock] = newEvent; hSockArr[ numOfClntSock] = hClentSock; numOfClntSock++ ; printf ( "connected new client..." ) ; } if ( netEvents. lNetworkEvents & FD_READ) { if ( netEvents. iErrorCode[ FD_READ_BIT] != 0 ) { printf ( "read error" ) ; return - 6 ; } int strLen = recv ( hSockArr[ sigEventIdx] , msg, sizeof ( msg) , 0 ) ; send ( hSockArr[ sigEventIdx] , msg, strLen, 0 ) ; } if ( netEvents. lNetworkEvents & FD_CLOSE) { if ( netEvents. iErrorCode[ FD_CLOSE_BIT] != 0 ) { printf ( "Close Error" ) ; break ; } WSACloseEvent ( hEventArr[ sigEventIdx] ) ; closesocket ( hSockArr[ sigEventIdx] ) ; numOfClntSock-- ; CompressEvent ( hEventArr, sigEventIdx, numOfClntSock) ; CompressSockets ( hSockArr, sigEventIdx, numOfClntSock) ; } } } } WSACleanup ( ) ; return 0 ;
} void CompressSockets ( SOCKET hSockArr[ ] , int idx, int total)
{ for ( int i= idx; i < total; i++ ) { hSockArr[ i] = hSockArr[ i + 1 ] ; }
}
void CompressEvent ( WSAEVENT hEventArr[ ] , int idx, int total)
{ for ( int i= idx; i < total; i++ ) { hEventArr[ i] = hEventArr[ i + 1 ] ; }
}