Windows Socket IO模型之 阻塞模式

    技术2024-08-17  63

    # include < winsock2. h># include < ws2tcpip. h># include "resolve.h"# include "public.h"typedef SINGLE_LIST_HEADER BuffHeader;typedef struct _CONNECTION_OBJ{     SOCKET s; // Client socket     HANDLE hRecvSema; // Semaphore incremented for each receive     BuffHeader buff;} CONNECTION_OBJ;volatile LONG gConnectedClients = 0; CONNECTION_OBJ* GetConnectObj( SOCKET s) {     CONNECTION_OBJ * newobj = NULL ;     newobj = ( CONNECTION_OBJ * ) HeapAlloc( GetProcessHeap( ) , HEAP_ZERO_MEMORY, sizeof ( CONNECTION_OBJ) ) ;     if ( newobj = = NULL ) {         fprintf ( stderr , "heapalloc failed./n" ) ;         ExitProcess( - 1) ;     }     newobj- > s = s;     newobj- > hRecvSema = CreateSemaphore( NULL , 0, 0x0FFFFFFF, NULL ) ;     if ( newobj- > hRecvSema = = NULL ) {         fprintf ( stderr , "createsimaphore failed./n" ) ;         ExitProcess( - 1) ;     }     newobj- > buff. head = newobj- > buff. tail = NULL ;     InitializeCriticalSection( & newobj- > buff. SendRecvQueueCritSec) ;     return newobj;}void FreeConnectionObj( CONNECTION_OBJ * obj) {     DeleteCriticalSection( & obj- > buff. SendRecvQueueCritSec) ;     HeapFree( GetProcessHeap( ) , 0, obj) ;} DWORD WINAPI ReceiveThread( LPVOID lpParam) {     CONNECTION_OBJ * ConnObj= NULL ;     BUFFER_OBJ * BuffObj= NULL ;     int rc;     ConnObj = ( CONNECTION_OBJ * ) lpParam;     if ( gProtocol = = IPPROTO_TCP ) {         while ( true ) {             BuffObj = GetBufferObj( gBufferSize) ;             rc = recv ( ConnObj- > s, BuffObj- > buf, BuffObj- > buflen, 0) ;             BuffObj- > buflen = rc;             EnqueueBufferObj( & ConnObj- > buff, & ( BuffObj- > next) ) ;                          ReleaseSemaphore( ConnObj- > hRecvSema, 1, NULL ) ;             if ( rc = = 0 | | rc = = SOCKET_ERROR) {                 break ;             } else if ( rc ! = SOCKET_ERROR) {                 printf ( "Read Bytes: %d/n" , rc) ;             }         }     }     ExitProcess( 0) ;     return 0;} DWORD WINAPI SendThread( LPVOID lpParam) {     CONNECTION_OBJ * ConnObj= NULL ;     BUFFER_OBJ * BuffObj= NULL ;     int rc,                     nleft,                     idx;     SINGLE_LIST* block;     ConnObj = ( CONNECTION_OBJ* ) lpParam;     while ( true ) {         rc = WaitForSingleObject( ConnObj- > hRecvSema, INFINITE) ;         if ( ( rc = = WAIT_FAILED) | | ( rc = = WAIT_TIMEOUT) ) {             fprintf ( stderr , "Send thread failed./n" ) ;             ExitProcess( - 1) ;         }         block = DequeueBufferObj( & ConnObj- > buff) ;         if ( block = = NULL )             ExitProcess( - 1) ;         BuffObj = ( BUFFER_OBJ* ) container_of( BUFFER_OBJ, next, block) ;         if ( ( ( gProtocol = = IPPROTO_TCP ) & & ( BuffObj- > buflen = = 0) ) | | ( BuffObj- > buflen = = SOCKET_ERROR) ) {             FreeBufferObj( BuffObj) ;             BuffObj = NULL ;             break ;         }         if ( gProtocol = = IPPROTO_TCP ) {             nleft = BuffObj- > buflen;             idx = 0;             while ( nleft > 0) {                 rc = send ( ConnObj- > s, BuffObj- > buf, BuffObj- > buflen, 0) ;                 if ( rc = = SOCKET_ERROR)                 {                     break ;                 }                 else                 {                     nleft - = rc;                     idx + = rc;                 }             }         }         FreeBufferObj( BuffObj) ;         BuffObj = NULL ;     }     closesocket( ConnObj- > s) ;     FreeConnectionObj( ConnObj) ;     ExitProcess( - 1) ;     return 0;} DWORD WINAPI ServerListenThread( LPVOID param) {     CONNECTION_OBJ * ConnObj= NULL ;     HANDLE hThread = NULL ;     SOCKET s;     int rc;     s = ( SOCKET ) param;     if ( gProtocol = = IPPROTO_TCP ) {         SOCKADDR_STORAGE saAccept;         SOCKET ns;         int acceptlen = sizeof ( SOCKADDR_STORAGE) ;         rc = listen ( s, 200) ;         if ( rc = = SOCKET_ERROR) {             fprintf ( stderr , "listen failed" ) ;             return - 1;         }         while ( true ) {             ns = accept ( s, ( SOCKADDR * ) & saAccept, & acceptlen) ;             if ( ns = = INVALID_SOCKET) {                 fprintf ( stderr , "accept failed./n" ) ;                 return - 1;             }             InterlockedIncrement( & gConnectedClients) ;             ConnObj = GetConnectObj( ns) ;             hThread = CreateThread( NULL , 0, SendThread, ( LPVOID) ConnObj, 0, NULL ) ;             if ( hThread = = NULL ) {                 fprintf ( stderr , "Create thread 0./n" ) ;                 return - 1;             }             CloseHandle( hThread) ;             hThread = CreateThread( NULL , 0, ReceiveThread, ( LPVOID) ConnObj, 0, NULL ) ;             if ( hThread = = NULL ) {                 fprintf ( stderr , "Create thread 1./n" ) ;                 return - 1;             }             CloseHandle( hThread) ;         }     }     closesocket( s) ;     ExitThread( 0) ;     return 0;}int _tmain( int argc, _TCHAR* argv[ ] ){     WSADATA wsd;     SOCKET s[ MAX_LISTEN_SOCKETS] ;     HANDLE threads[ MAX_LISTEN_SOCKETS] ;     struct addrinfo * res = NULL ;     struct addrinfo * ptr = NULL ;     int listencount = 0;     int rc = 0;     int i;     if ( WSAStartup( MAKEWORD( 2, 2) , & wsd) ! = 0) {         fprintf ( stderr , "unable load to winsock!/n" ) ;         return - 1;     }     res = ResolveAddress( gSrvAddr, gPort, gAddressFamily, gSocketType, gProtocol) ;     if ( res = = NULL ) {         fprintf ( stderr , "resolve addr failed./n" ) ;         return - 1;     }     ptr = res;     while ( ptr) {         if ( listencount > MAX_LISTEN_SOCKETS) {             fprintf ( stderr , "big than MAX_LISTEN_SOCKETS./n" ) ;             return - 1;         }         s[ listencount] = socket ( ptr- > ai_family, ptr- > ai_socktype, ptr- > ai_protocol) ;         if ( s[ listencount] = = INVALID_SOCKET) {             fprintf ( stderr , "socket failed./n" ) ;             return - 1;         }         rc = bind ( s[ listencount] , ptr- > ai_addr, ptr- > ai_addrlen) ;         if ( rc = = SOCKET_ERROR) {             fprintf ( stderr , "bind failed.%d/n" , WSAGetLastError( ) ) ;             return - 1;         }         threads[ listencount] = CreateThread( NULL , 0, ServerListenThread, ( LPVOID) s[ listencount] , 0, NULL ) ;         if ( threads[ listencount] = = NULL ) {             fprintf ( stderr , "Create listen task faileds./n" ) ;             return - 1;         }         + + listencount;         ptr = ptr- > ai_next;     }     freeaddrinfo ( res) ;     while ( true ) {         rc = WaitForMultipleObjects( listencount, threads, TRUE , INFINITE) ;         if ( rc = = WAIT_TIMEOUT) {             fprintf ( stderr , "wait timeout./n" ) ;             return - 1;         } else if ( rc = = WAIT_FAILED) {             fprintf ( stderr , "wait error./n" ) ;             return - 1;         } else             break ;     }     for ( i= 0; i < listencount ; i+ + )     {         CloseHandle( threads[ i] ) ;     }     WSACleanup( ) ;     return 0;}

     

    版权声明: 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。

    最新回复(0)