Windows网络编程:Complete Routine的基本使用

Windows网络编程:Complete Routine的基本使用
Complete Routine的基本使用,下面是一个简单的例子
#include  < winsock2.h >
#include 
< stdio.h >

#pragma comment(lib, 
" ws2_32.lib " )

#define  LISTEN_PORT 5080
#define  BUFF_SIZE   256

void  CALLBACK WorkerRoutine(DWORD error, DWORD bytes_transferred, 
                            LPWSAOVERLAPPED overlapped,
                             DWORD inflags);

typedef 
struct  
{
    WSAOVERLAPPED overlapped;
    DWORD         recv_bytes;
    SOCKET        client_sock;
    DWORD         inflags;
    WSABUF        buff;
}SOCKINFO;

int  main( void )
{
    WSADATA wsaData;
    
int  nRet;
    SOCKET listen_sock;
    SOCKADDR_IN listen_addr;
    SOCKET client_sock;
    SOCKADDR_IN client_addr;
    
int  client_addr_len  =   sizeof (client_addr);
    
char  buff[BUFF_SIZE];
    DWORD recv_bytes 
=   0 ;
    
int  index;
    SOCKINFO sockInfo;
    WSAEVENT wsaEvent;

    nRet 
=  WSAStartup(MAKEWORD( 2 , 2 ),  & wsaData);
    
if ( 0   !=  nRet)
    {
        printf(
" WSAStartup() failed, error:%d.\n " , WSAGetLastError());
        
return   1 ;
    }

    listen_sock 
=  socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
if (INVALID_SOCKET  ==  listen_sock)
    {
        printf(
" socket() failed, error:%d.\n " , WSAGetLastError());
        
goto  retflag1;
    }

    listen_addr.sin_family 
=  AF_INET;
    listen_addr.sin_addr.s_addr 
=  htonl(INADDR_ANY);
    listen_addr.sin_port 
=  htons(LISTEN_PORT);
    nRet 
=  bind(listen_sock, (SOCKADDR * ) & listen_addr,  sizeof (listen_addr));
    
if (nRet  ==  SOCKET_ERROR)
    {
        printf(
" bind() failed, error:%d.\n " , WSAGetLastError());
        closesocket(listen_sock);
        
goto  retflag1;
    }

    nRet 
=  listen(listen_sock,  5 );
    
if (SOCKET_ERROR  ==  nRet)
    {
        printf(
" listen() failed, error:%d.\n " , WSAGetLastError());
        closesocket(listen_sock);
        
goto  retflag1;
    }

    client_sock 
=  accept(listen_sock, (SOCKADDR * ) & client_addr,  & client_addr_len);
    
if (INVALID_SOCKET  ==  client_sock)
    {
        printf(
" accept failed, error:%d.\n " , WSAGetLastError());
        closesocket(listen_sock);
        
goto  retflag1;
    }

    sockInfo.inflags 
=   0 ;
    memset(
& sockInfo.overlapped,  0 sizeof (sockInfo.overlapped));
    sockInfo.client_sock 
=  client_sock;
    sockInfo.buff.buf 
=  buff;
    sockInfo.buff.len 
=  BUFF_SIZE;

    sockInfo.overlapped.hEvent 
=  (HANDLE) & sockInfo;

    
if (WSARecv(client_sock,  & sockInfo.buff,  1 & sockInfo.recv_bytes,  & sockInfo.inflags,  & sockInfo.overlapped, WorkerRoutine)  ==  SOCKET_ERROR)
    {
        
if (WSAGetLastError()  ==  WSA_IO_PENDING)
        {
            printf(
" WSARecv() WSA_IO_PENDING.\n " );
        }
        
else
        {
            printf(
" WSARecv failed, error:%d.\n " , WSAGetLastError());
            closesocket(listen_sock);
            closesocket(client_sock);
            
goto  retflag1;
        }
    }

    wsaEvent 
=  WSACreateEvent();
    
if (WSA_INVALID_EVENT  ==  wsaEvent)
    {
        printf(
" WSACreateEvent() failed, error:%d.\n " , WSAGetLastError());
        closesocket(listen_sock);
        closesocket(client_sock);
        
goto  retflag1;
    }

    
while ( 1 )
    {
        index 
=  WSAWaitForMultipleEvents( 1 & wsaEvent, FALSE, WSA_INFINITE, TRUE);
        
if (index  =  WAIT_IO_COMPLETION)
        {
            
continue ;
        }
        
else
        {
            printf(
" WSAWaitForMultipleEvents() failed, error:%d.\n " , WSAGetLastError());
            closesocket(listen_sock);
            closesocket(client_sock);
            WSACloseEvent(wsaEvent);
            
goto  retflag1;
        }
    }

    closesocket(listen_sock);
    closesocket(client_sock);
    WSACloseEvent(wsaEvent);

retflag1:
    nRet 
=  WSACleanup();
    
if ( 0   !=  nRet)
    {
        printf(
" WSACleanup() failed, error:%d.\n " , WSAGetLastError());
        
return   1 ;
    }
    
return   0 ;
}

void  CALLBACK WorkerRoutine(DWORD error, DWORD bytes_transferred, 
                            LPWSAOVERLAPPED overlapped,
                            DWORD inflags)
{
    SOCKINFO
*  sockInfo  =  NULL;
    
if (error  !=   0 )
    {
        printf(
" Callback error:%d.\n " , error);
        
return ;
    }
    
if (bytes_transferred  ==   0 )
    {
        printf(
" peer closed.\n " );
        
return ;
    }

    sockInfo 
=  (SOCKINFO * )overlapped -> hEvent;
    printf(
" %s " , sockInfo -> buff.buf);
    sockInfo
-> inflags  =   0 ;
    memset(
& sockInfo -> overlapped,  0 sizeof (sockInfo -> overlapped));
    sockInfo
-> overlapped.hEvent  =  (HANDLE)sockInfo;

    
if (WSARecv(sockInfo -> client_sock,  & sockInfo -> buff,  1 & sockInfo -> recv_bytes,  & sockInfo -> inflags,  & sockInfo -> overlapped, WorkerRoutine)  ==  SOCKET_ERROR)
    {
        
if (WSAGetLastError()  ==  WSA_IO_PENDING)
        {
            printf(
" WSARecv() WSA_IO_PENDING.\n " );
        }
        
else
        {
            printf(
" WSARecv failed, error:%d.\n " , WSAGetLastError());
            
return ;
        }
    }

}

你可能感兴趣的:(Windows网络编程:Complete Routine的基本使用)