- # include < winsock2. h>
- # include < ws2tcpip. h>
- # include < mswsock. h>
- # include < windows. h>
- # include "resolve.h"
- # include "public.h"
- # define DEFAULT_OVERLAPPED_COUNT 5
- # define MAX_COMPLETION_THREAD_COUNT 32 // Maximum number of completion threads allowed
- typedef SINGLE_LIST_HEADER SocketObjHeader;
- typedef SINGLE_LIST SocketObj;
- typedef DOUBLE_LIST_HEADER BufferObjHeader;
- typedef DOUBLE_LIST BufferObj;
- int gOverlappedCount = DEFAULT_OVERLAPPED_COUNT;
- typedef struct _BUFFER_OBJ_EX {
- WSAOVERLAPPED ol; // Overlapped structure
- SOCKET sclient; // Used for AcceptEx client socket
- char * buf; // Buffer for send/recv/AcceptEx
- int buflen; // Length of the buffer
- int operation; // Type of operation submitted
- # define OP_ACCEPT 0 // AcceptEx
- # define OP_READ 1 // WSARecv/WSARecvFrom
- # define OP_WRITE 2 // WSASend?WSASendTo
- SOCKADDR_STORAGE addr; // Remote address (UDP)
- int addrlen; // Remote address length
- ULONG IoOrder; // Order in which this I/O was posted
- BufferObj bufDList;
- } BUFFER_OBJ_EX;
- typedef struct _SOCKET_OBJ
- {
- SOCKET s; // Socket handle for client connection
- int af, // Address family of socket (AF_INET or AF_INET6)
- bClosing; // Indicates socket is closing
- volatile LONG OutstandingOps; // Number of outstanding overlapped ops
- BUFFER_OBJ_EX * * PendingAccepts; // Array of pending AcceptEx calls (listening socket only)
- ULONG LastSendIssued, // Last sequence number sent
- IoCountIssued; // Next sequence number assigned to receives
- BufferObjHeader OutOfOrderSends; // List of send buffers that completed out of order
- // Pointers to Microsoft specific extensions (listening socket only)
- LPFN_ACCEPTEX lpfnAcceptEx;
- LPFN_GETACCEPTEXSOCKADDRS lpfnGetAcceptExSockaddrs;
- CRITICAL_SECTION SockCritSec; // Synchronize access to this SOCKET_OBJ
- SocketObj next; // Used to chain SOCKET_OBJ together
- } SOCKET_OBJ;
- SOCKET_OBJ * GetSocketObj( SOCKET s, int af)
- {
- SOCKET_OBJ * sockobj= NULL ;
- sockobj = ( SOCKET_OBJ * ) HeapAlloc( GetProcessHeap( ) , HEAP_ZERO_MEMORY, sizeof ( SOCKET_OBJ) ) ;
- if ( sockobj = = NULL )
- {
- fprintf ( stderr , "GetSocketObj: HeapAlloc failed: %d/n" , GetLastError( ) ) ;
- ExitProcess( - 1) ;
- }
- InitializeCriticalSection( & sockobj- > SockCritSec) ;
- InitializeDoubleHead( & sockobj- > OutOfOrderSends) ;
- sockobj- > IoCountIssued = ( ( gProtocol = = IPPROTO_TCP ) ? 1 : 0) ;
- // Initialize the members
- sockobj- > s = s;
- sockobj- > af = af;
- return sockobj;
- }
- BUFFER_OBJ_EX * GetBufferObjEx( int buflen)
- {
- BUFFER_OBJ_EX * newobj= NULL ;
- // Allocate the object
- newobj = ( BUFFER_OBJ_EX * ) HeapAlloc( GetProcessHeap( ) , HEAP_ZERO_MEMORY, sizeof ( BUFFER_OBJ_EX) ) ;
- if ( newobj = = NULL ) {
- printf ( "GetBufferObj: HeapAlloc failed: %d/n" , GetLastError( ) ) ;
- ExitProcess( - 1) ;
- }
- // Allocate the buffer
- newobj- > buf = ( char * ) HeapAlloc( GetProcessHeap( ) , HEAP_ZERO_MEMORY, sizeof ( BYTE) * buflen) ;
- if ( newobj- > buf = = NULL ) {
- printf ( "GetBufferObj: HeapAlloc failed: %d/n" , GetLastError( ) ) ;
- ExitProcess( - 1) ;
- }
- newobj- > buflen = buflen;
- newobj- > addrlen = sizeof ( newobj- > addr) ;
- return newobj;
- }
- void FreeBufferObjEx( BUFFER_OBJ_EX * obj)
- {
- HeapFree( GetProcessHeap( ) , 0, obj- > buf) ;
- HeapFree( GetProcessHeap( ) , 0, obj) ;
- }
- void FreeSocketObj( SOCKET_OBJ * obj)
- {
- BUFFER_OBJ_EX * ptr= NULL ,
- * tmp= NULL ;
- if ( obj- > OutstandingOps ! = 0)
- {
- // Still outstanding operations so just return
- return ;
- }
- // Close the socket if it hasn't already been closed
- if ( obj- > s ! = INVALID_SOCKET)
- {
- closesocket( obj- > s) ;
- obj- > s = INVALID_SOCKET;
- }
- DeleteCriticalSection( & obj- > SockCritSec) ;
- HeapFree( GetProcessHeap( ) , 0, obj) ;
- }
- void InsertPendingSend( SOCKET_OBJ * sock, BUFFER_OBJ_EX * send )
- {
- BufferObj * ptr = NULL ;
- BUFFER_OBJ_EX * obj = NULL ;
- EnterCriticalSection( & sock- > SockCritSec) ;
- ptr = ( BufferObj * ) GotoNextDoubleList( & sock- > OutOfOrderSends, & sock- > OutOfOrderSends. head) ;
- while ( ptr)
- {
- obj = ( BUFFER_OBJ_EX * ) container_of( BUFFER_OBJ_EX, bufDList, ptr) ;
- if ( send - > IoOrder < obj- > IoOrder)
- {
- break ;
- }
- ptr = ( BufferObj * ) GotoNextDoubleList( & sock- > OutOfOrderSends, ptr) ;
- }
- if ( ptr = = NULL )
- ptr = & sock- > OutOfOrderSends. head;
- EnqueueDoubleListBefore( & sock- > OutOfOrderSends, ptr, & send - > bufDList) ;
- LeaveCriticalSection( & sock- > SockCritSec) ;
- }
- int PostRecv( SOCKET_OBJ * sock, BUFFER_OBJ_EX * recvobj)
- {
- WSABUF wbuf;
- DWORD bytes,
- flags;
- int rc;
- recvobj- > operation = OP_READ;
- wbuf. buf = recvobj- > buf;
- wbuf. len = recvobj- > buflen;
- flags = 0;
- EnterCriticalSection( & sock- > SockCritSec) ;
- // Assign the IO order to this receive. This must be performned within
- // the critical section. The operation of assigning the IO count and posting
- // the receive cannot be interupted.
- recvobj- > IoOrder = sock- > IoCountIssued;
- sock- > IoCountIssued+ + ;
- if ( gProtocol = = IPPROTO_TCP )
- {
- rc = WSARecv(
- sock- > s,
- & wbuf,
- 1,
- & bytes,
- & flags,
- & recvobj- > ol,
- NULL
- ) ;
- }
- else
- {
- ExitProcess( - 1) ;
- }
- LeaveCriticalSection( & sock- > SockCritSec) ;
- if ( rc = = SOCKET_ERROR)
- {
- if ( WSAGetLastError( ) ! = WSA_IO_PENDING)
- {
- fprintf ( stderr , "PostRecv: WSARecv* failed: %d/n" , WSAGetLastError( ) ) ;
- return SOCKET_ERROR;
- }
- }
- // Increment outstanding overlapped operations
- InterlockedIncrement( & sock- > OutstandingOps) ;
- return NO_ERROR;
- }
- int sendnum = 0;
- int PostSend( SOCKET_OBJ * sock, BUFFER_OBJ_EX * sendobj)
- {
- WSABUF wbuf;
- DWORD bytes;
- int rc;
- sendobj- > operation = OP_WRITE;
- wbuf. buf = sendobj- > buf;
- wbuf. len = sendobj- > buflen;
- EnterCriticalSection( & sock- > SockCritSec) ;
- // Incrmenting the last send issued and issuing the send should not be
- // interuptable.
- sock- > LastSendIssued+ + ;
- if ( gProtocol = = IPPROTO_TCP )
- {
- printf ( "send %d/n" , sendnum+ + ) ;
- rc = WSASend(
- sock- > s,
- & wbuf,
- 1,
- & bytes,
- 0,
- & sendobj- > ol,
- NULL
- ) ;
- }
- else {
- ExitProcess( - 1) ;
- }
- LeaveCriticalSection( & sock- > SockCritSec) ;
- if ( rc = = SOCKET_ERROR)
- {
- if ( WSAGetLastError( ) ! = WSA_IO_PENDING)
- {
- fprintf ( stderr , "PostSend: WSASend* failed: %d/n" , WSAGetLastError( ) ) ;
- return SOCKET_ERROR;
- }
- }
- // Increment the outstanding operation count
- InterlockedIncrement( & sock- > OutstandingOps) ;
- return NO_ERROR;
- }
- int PostAccept( SOCKET_OBJ * sock, BUFFER_OBJ_EX * acceptobj)
- {
- DWORD bytes;
- int rc;
- acceptobj- > operation = OP_ACCEPT;
- // Create the client socket for an incoming connection
- acceptobj- > sclient = socket ( sock- > af, SOCK_STREAM , IPPROTO_TCP ) ;
- if ( acceptobj- > sclient = = INVALID_SOCKET)
- {
- fprintf ( stderr , "PostAccept: socket failed: %d/n" , WSAGetLastError( ) ) ;
- return - 1;
- }
- rc = sock- > lpfnAcceptEx(
- sock- > s,
- acceptobj- > sclient,
- acceptobj- > buf,
- acceptobj- > buflen - ( ( sizeof ( SOCKADDR_STORAGE) + 16) * 2) ,
- sizeof ( SOCKADDR_STORAGE) + 16,
- sizeof ( SOCKADDR_STORAGE) + 16,
- & bytes,
- & acceptobj- > ol
- ) ;
- if ( rc = = FALSE )
- {
- if ( WSAGetLastError( ) ! = WSA_IO_PENDING)
- {
- fprintf ( stderr , "PostAccept: AcceptEx failed: %d/n" , WSAGetLastError( ) ) ;
- return SOCKET_ERROR;
- }
- }
- // Increment the outstanding overlapped count for this socket
- InterlockedIncrement( & sock- > OutstandingOps) ;
- return NO_ERROR;
- }
- int DoSends( SOCKET_OBJ * sock)
- {
- BufferObj * ptr = NULL ;
- BufferObj * tmp = NULL ;
- BUFFER_OBJ_EX * sendobj = NULL ;
- int ret;
- ret = NO_ERROR;
- EnterCriticalSection( & sock- > SockCritSec) ;
- ptr = ( BufferObj * ) GotoNextDoubleList( & sock- > OutOfOrderSends, & sock- > OutOfOrderSends. head) ;
- while ( ptr) {
- sendobj = ( BUFFER_OBJ_EX * ) container_of( BUFFER_OBJ_EX, bufDList, ptr) ;
- if ( ( sendobj) & & ( sendobj- > IoOrder = = sock- > LastSendIssued) )
- {
- if ( PostSend( sock, sendobj) ! = NO_ERROR)
- {
- FreeBufferObjEx( sendobj) ;
- ret = SOCKET_ERROR;
- break ;
- }
- } else
- break ;
- tmp = ptr;
- ptr = ( BufferObj * ) GotoNextDoubleList( & sock- > OutOfOrderSends, ptr) ;
- RemoveDoubleList( & sock- > OutOfOrderSends, tmp) ;
- //FreeBufferObjEx(sendobj);
- }
- LeaveCriticalSection( & sock- > SockCritSec) ;
- return ret;
- }
- int handleNum = 0;
- int handlecut = 0;
- void HandleIo( SOCKET_OBJ * sock, BUFFER_OBJ_EX * buf, HANDLE CompPort, DWORD BytesTransfered, DWORD error ) {
- SOCKET_OBJ * clientobj= NULL ; // New client object for accepted connections
- BUFFER_OBJ_EX * recvobj= NULL , // Used to post new receives on accepted connections
- * sendobj= NULL ; // Used to post new sends for data received
- BOOL bCleanupSocket;
- char * tmp;
- int i;
- bCleanupSocket = FALSE ;
- if ( ( error ! = NO_ERROR) & & ( gProtocol = = IPPROTO_TCP ) ) {
- FreeBufferObjEx( buf) ;
- if ( InterlockedDecrement( & sock- > OutstandingOps) = = 0) {
- FreeSocketObj( sock) ;
- }
- return ;
- }
- EnterCriticalSection( & sock- > SockCritSec) ;
- if ( buf- > operation = = OP_ACCEPT) {
- HANDLE hrc;
- SOCKADDR_STORAGE * LocalSockaddr= NULL ,
- * RemoteSockaddr= NULL ;
- int LocalSockaddrLen,
- RemoteSockaddrLen;
- sock- > lpfnGetAcceptExSockaddrs(
- buf- > buf, buf- > buflen - ( ( sizeof ( SOCKADDR_STORAGE) + 16) * 2) ,
- sizeof ( SOCKADDR_STORAGE) + 16, sizeof ( SOCKADDR_STORAGE) + 16,
- ( SOCKADDR * * ) & LocalSockaddr, & LocalSockaddrLen,
- ( SOCKADDR * * ) & RemoteSockaddr, & RemoteSockaddrLen) ;
- clientobj = GetSocketObj( buf- > sclient, sock- > af) ;
- hrc = CreateIoCompletionPort( ( HANDLE) buf- > sclient, CompPort, ( ULONG_PTR) clientobj, 0) ;
- if ( hrc = = NULL ) {
- fprintf ( stderr , "CompletionThread: CreateIoCompletionPort failed: %d/n" , GetLastError( ) ) ;
- return ;
- }
- sendobj = GetBufferObjEx( BytesTransfered) ;
- memcpy ( sendobj- > buf, buf- > buf, BytesTransfered) ;
- if ( PostSend( clientobj, sendobj) = = NO_ERROR)
- {
- // Now post some receives on this new connection
- for ( i = 0; i < gOverlappedCount; i+ + )
- {
- recvobj = GetBufferObjEx( gBufferSize) ;
- if ( PostRecv( clientobj, recvobj) ! = NO_ERROR)
- {
- FreeBufferObjEx( recvobj) ;
- error = SOCKET_ERROR;
- break ;
- }
- }
- }
- else
- {
- FreeBufferObjEx( sendobj) ;
- error = SOCKET_ERROR;
- }
- PostAccept( sock, buf) ;
- if ( error ! = NO_ERROR)
- {
- if ( clientobj- > OutstandingOps = = 0)
- {
- closesocket( clientobj- > s) ;
- clientobj- > s = INVALID_SOCKET;
- FreeSocketObj( clientobj) ;
- }
- else
- {
- clientobj- > bClosing = TRUE ;
- }
- error = NO_ERROR;
- }
- } else if ( ( buf- > operation = = OP_READ) & & ( error = = NO_ERROR) ) {
- if ( ( BytesTransfered > 0) )
- {
- printf ( "HandleIo: %d/n" , handleNum+ + ) ;
- // Create a buffer to send
- sendobj = GetBufferObjEx( gBufferSize) ;
- printf ( "handlecut %d./n" , handlecut+ + ) ;
- // Swap the buffers (i.e. buffer we just received becomes the send buffer)
- tmp = sendobj- > buf;
- sendobj- > buflen = BytesTransfered;
- sendobj- > buf = buf- > buf;
- sendobj- > IoOrder = buf- > IoOrder;
- buf- > buf = tmp;
- buf- > buflen = gBufferSize;
- InsertPendingSend( sock, sendobj) ;
- if ( DoSends( sock) ! = NO_ERROR)
- {
- error = SOCKET_ERROR;
- printf ( "SOCKET_ERROR./n" ) ;
- }
- else
- {
- // Post another receive
- if ( PostRecv( sock, buf) ! = NO_ERROR)
- {
- // In the event the recv fails, clean up the connection
- FreeBufferObjEx( buf) ;
- error = SOCKET_ERROR;
- printf ( "SOCKET_ERROR./n" ) ;
- }
- }
- }
- else
- {
- sock- > bClosing = TRUE ;
- // Free the receive buffer
- FreeBufferObjEx( buf) ;
- if ( DoSends( sock) ! = NO_ERROR)
- {
- error = SOCKET_ERROR;
- printf ( "SOCKET_ERROR./n" ) ;
- }
- // If this was the last outstanding operation on socket, clean it up
- if ( ( sock- > OutstandingOps = = 0) & & ( sock- > OutOfOrderSends. count = = 0) )
- {
- bCleanupSocket = TRUE ;
- }
- }
- } else if ( buf- > operation = = OP_WRITE) {
- FreeBufferObjEx( buf) ;
- if ( DoSends( sock) ! = NO_ERROR)
- {
- error = SOCKET_ERROR;
- }
- }
- if ( error ! = NO_ERROR) {
- sock- > bClosing = TRUE ;
- }
- if ( ( InterlockedDecrement( & sock- > OutstandingOps) = = 0) & & ( sock- > bClosing) & & ( sock- > OutOfOrderSends. count = = 0) ) {
- bCleanupSocket = TRUE ;
- } else {
- if ( DoSends( sock) ! = NO_ERROR) {
- bCleanupSocket = TRUE ;
- }
- }
- LeaveCriticalSection( & sock- > SockCritSec) ;
- if ( bCleanupSocket)
- {
- closesocket( sock- > s) ;
- sock- > s = INVALID_SOCKET;
- FreeSocketObj( sock) ;
- }
- }
- int iocpNum = 0;
- DWORD WINAPI CompletionThread( LPVOID lpParam) {
- SOCKET_OBJ * sockobj= NULL ; // Per socket object for completed I/O
- BUFFER_OBJ_EX * bufobj= NULL ; // Per I/O object for completed I/O
- OVERLAPPED * lpOverlapped= NULL ; // Pointer to overlapped structure for completed I/O
- HANDLE CompletionPort; // Completion port handle
- DWORD BytesTransfered, // Number of bytes transfered
- Flags; // Flags for completed I/O
- int rc,
- error ;
- CompletionPort = ( HANDLE) lpParam;
- while ( true ) {
- error = NO_ERROR;
- rc = GetQueuedCompletionStatus( CompletionPort, & BytesTransfered, ( PULONG_PTR) & sockobj, & lpOverlapped, INFINITE) ;
- printf ( "iocp %d./n" , iocpNum+ + ) ;
- bufobj = CONTAINING_RECORD( lpOverlapped, BUFFER_OBJ_EX, ol) ;
- if ( rc = = FALSE )
- {
- printf ( "false./n" ) ;
- rc = WSAGetOverlappedResult( sockobj- > s, & bufobj- > ol, & BytesTransfered, FALSE , & Flags) ;
- if ( rc = = FALSE )
- {
- error = WSAGetLastError( ) ;
- printf ( "WSAGetOverlappedResult failed %d./n" , error ) ;
- }
- }
- HandleIo( sockobj, bufobj, CompletionPort, BytesTransfered, error ) ;
- }
- ExitProcess( 0) ;
- return 0;
- }
- int _tmain( int argc, _TCHAR* argv[ ] )
- {
- WSADATA wsd;
- SYSTEM_INFO sysinfo;
- SOCKET_OBJ * sockobj= NULL ;
- SocketObjHeader ListenSockets;
- HANDLE CompletionPort,
- CompThreads[ MAX_COMPLETION_THREAD_COUNT] ,
- hrc;
- int endpointcount= 0,
- interval,
- rc,
- i;
- struct addrinfo * res= NULL ,
- * ptr= NULL ;
- if ( WSAStartup( MAKEWORD( 2, 2) , & wsd) ! = 0)
- {
- fprintf ( stderr , "unable to load Winsock!/n" ) ;
- return - 1;
- }
- CompletionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL , NULL , 0) ;
- if ( CompletionPort = = NULL ) {
- fprintf ( stderr , "CreateIoCompletionPort failed./n" ) ;
- return 0;
- }
- GetSystemInfo( & sysinfo) ;
- if ( sysinfo. dwNumberOfProcessors > MAX_COMPLETION_THREAD_COUNT) {
- sysinfo. dwNumberOfProcessors = MAX_COMPLETION_THREAD_COUNT;
- }
- //for (i = 0; i < sysinfo.dwNumberOfProcessors; ++i) {
- for ( i = 0; i < 1; + + i) {
- CompThreads[ i] = CreateThread( NULL , 0, CompletionThread, ( LPVOID) CompletionPort, 0, NULL ) ;
- if ( CompThreads[ i] = = NULL ) {
- fprintf ( stderr , "CreateThread failed./n" ) ;
- return - 1;
- }
- }
- res = ResolveAddress( gSrvAddr, gPort, gAddressFamily, gSocketType, gProtocol) ;
- if ( res = = NULL )
- {
- fprintf ( stderr , "ResolveAddress failed to return any addresses!/n" ) ;
- return - 1;
- }
- InitializeSingleHead( & ListenSockets) ;
- ptr = res;
- while ( ptr) {
- sockobj = GetSocketObj( INVALID_SOCKET, ptr- > ai_family) ;
- sockobj- > s = socket ( ptr- > ai_family, ptr- > ai_socktype, ptr- > ai_protocol) ;
- if ( sockobj- > s = = INVALID_SOCKET)
- {
- fprintf ( stderr , "socket failed: %d/n" , WSAGetLastError( ) ) ;
- return - 1;
- }
- hrc = CreateIoCompletionPort( ( HANDLE) sockobj- > s, CompletionPort, ( ULONG_PTR) sockobj, 0) ;
- if ( hrc = = NULL )
- {
- fprintf ( stderr , "CreateIoCompletionPort failed: %d/n" , GetLastError( ) ) ;
- return - 1;
- }
- rc = bind ( sockobj- > s, ptr- > ai_addr, ptr- > ai_addrlen) ;
- if ( rc = = SOCKET_ERROR) {
- fprintf ( stderr , "bind failed: %d/n" , WSAGetLastError( ) ) ;
- return - 1;
- }
- if ( gProtocol = = IPPROTO_TCP ) {
- BUFFER_OBJ_EX * acceptobj= NULL ;
- GUID guidAcceptEx = WSAID_ACCEPTEX,
- guidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
- DWORD bytes;
- // Need to load the Winsock extension functions from each provider
- // -- e.g. AF_INET and AF_INET6.
- rc = WSAIoctl( sockobj- > s, SIO_GET_EXTENSION_FUNCTION_POINTER, & guidAcceptEx, sizeof ( guidAcceptEx) ,
- & sockobj- > lpfnAcceptEx, sizeof ( sockobj- > lpfnAcceptEx) , & bytes, NULL , NULL ) ;
- if ( rc = = SOCKET_ERROR)
- {
- fprintf ( stderr , "WSAIoctl: SIO_GET_EXTENSION_FUNCTION_POINTER failed: %d/n" ,
- WSAGetLastError( ) ) ;
- return - 1;
- }
- rc = WSAIoctl( sockobj- > s, SIO_GET_EXTENSION_FUNCTION_POINTER, & guidGetAcceptExSockaddrs, sizeof ( guidGetAcceptExSockaddrs) ,
- & sockobj- > lpfnGetAcceptExSockaddrs, sizeof ( sockobj- > lpfnGetAcceptExSockaddrs) , & bytes, NULL , NULL ) ;
- if ( rc = = SOCKET_ERROR)
- {
- fprintf ( stderr , "WSAIoctl: SIO_GET_EXTENSION_FUNCTION_POINTER faled: %d/n" ,
- WSAGetLastError( ) ) ;
- return - 1;
- }
- rc = listen ( sockobj- > s, 100) ;
- if ( rc = = SOCKET_ERROR) {
- fprintf ( stderr , "listen failed: %d/n" , WSAGetLastError( ) ) ;
- return - 1;
- }
- sockobj- > PendingAccepts = ( BUFFER_OBJ_EX * * ) HeapAlloc( GetProcessHeap( ) , HEAP_ZERO_MEMORY, ( sizeof ( BUFFER_OBJ_EX * ) * gOverlappedCount) ) ;
- if ( sockobj- > PendingAccepts = = NULL )
- {
- fprintf ( stderr , "HeapAlloc failed: %d/n" , GetLastError( ) ) ;
- ExitProcess( - 1) ;
- }
- for ( i= 0; i < gOverlappedCount ; i+ + )
- {
- sockobj- > PendingAccepts[ i] = acceptobj = GetBufferObjEx( gBufferSize) ;
- PostAccept( sockobj, acceptobj) ;
- }
- EnqueueSingleList( & ListenSockets, & ( sockobj- > next) ) ;
- }
- ptr = ptr- > ai_next;
- }
- freeaddrinfo ( res) ;
- interval = 0;
- while ( true ) {
- rc = WSAWaitForMultipleEvents( 1, CompThreads, TRUE , 5000, FALSE ) ;
- if ( rc = = WAIT_FAILED) {
- fprintf ( stderr , "WSAWaitForMultipleEvents failed: %d/n" , WSAGetLastError( ) ) ;
- break ;
- } else if ( rc = = WAIT_TIMEOUT) {
- interval+ + ;
- if ( interval = = 12) {
- SocketObj * listenptr= NULL ;
- int optval,
- optlen;
- // Walk the list of outstanding accepts
- listenptr = ( SocketObj * ) GotoNextSingleList( & ListenSockets, ListenSockets. head) ;
- while ( listenptr)
- {
- sockobj = ( SOCKET_OBJ * ) container_of( SOCKET_OBJ, next, listenptr) ;
- for ( i= 0; i < gOverlappedCount ; i+ + )
- {
- optlen = sizeof ( optval) ;
- rc = getsockopt (
- sockobj- > PendingAccepts[ i] - > sclient,
- SOL_SOCKET,
- SO_CONNECT_TIME,
- ( char * ) & optval,
- & optlen
- ) ;
- if ( rc = = SOCKET_ERROR)
- {
- fprintf ( stderr , "getsockopt: SO_CONNECT_TIME failed: %d/n" , WSAGetLastError( ) ) ;
- return - 1;
- }
- if ( ( optval ! = 0xFFFFFFFF) & & ( optval > 300) )
- {
- closesocket( sockobj- > PendingAccepts[ i] - > sclient) ;
- }
- }
- listenptr = ( SocketObj * ) GotoNextSingleList( & ListenSockets, listenptr) ;
- }
- interval = 0;
- }
- }
- }
- WSACleanup( ) ;
- return 0;
- }
版权声明: 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。