异步通知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 ] ;
}
}