Windows网络编程:使用Completion Port

Windows网络编程:使用Completion Port
下面是使用Completion Port的一个简单的例子:
#include  < winsock2.h >
#include 
< windows.h >
#include 
< stdio.h >

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

#define  LISTEN_PORT 5080
#define  DATA_BUFSIZE 512

typedef 
struct
{
    WSAOVERLAPPED wsaOverlapped;
    WSABUF wsaBuf;
    
char  buffer[DATA_BUFSIZE];
}PER_IO_OPERATION_DATA, 
* LPPER_IO_OPERATION_DATA;

typedef 
struct
{
    SOCKET sock;
}PER_HANDLE_DATA, 
* LPPER_HANDLE_DATA;

DWORD WINAPI ServerWorkerThread(LPVOID lpCompletionPortID);

int  main()
{
    WSADATA wsaData;
    
int  nRet;
    HANDLE hCompletionPort;
    SYSTEM_INFO systemInfo;
    
int  i;
    HANDLE hThread;
    DWORD dwThreadID;
    SOCKET sockListen;
    SOCKADDR_IN listenAddr;
    SOCKET acceptSock;
    LPPER_HANDLE_DATA perHandleData;
    LPPER_IO_OPERATION_DATA lpPerIoOperationData;
    DWORD dwFlags;
    DWORD dwBytesRecv;

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

    
if ((hCompletionPort  =  CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL,  0 0 ))  ==  NULL)
    {
        printf(
" CreateIoCompletionPort() failed with error %d.\n " , GetLastError());
        WSACleanup();
        
return   1 ;
    }
    
else
    {
        printf(
" CreateIoCompletionPort() is OK.\n " );
    }

    GetSystemInfo(
& systemInfo);
    
for (i  =   0 ; i  <  ( int )systemInfo.dwNumberOfProcessors * 2 ++ i)
    {
        
if ((hThread  =  CreateThread(NULL,  0 , ServerWorkerThread, hCompletionPort,  0 & dwThreadID))  ==  NULL)
        {
            printf(
" CreateThread() failed with error %d.\n " , GetLastError());
            WSACleanup();
            
return   1 ;
        }
        
else
            printf(
" CreateThread() is OK! Thread ID:%d\n " , dwThreadID);

        CloseHandle(hThread);
    }

    
if ((sockListen  =  WSASocket(AF_INET, SOCK_STREAM,  0 , NULL,  0 , WSA_FLAG_OVERLAPPED))  ==  INVALID_SOCKET)
    {
        printf(
" WSASocket() failed with error %d.\n " , WSAGetLastError());
        WSACleanup();
        
return   1 ;
    }
    
else
    {
        printf(
" WSASocket() is OK!\n " );
    }

    listenAddr.sin_family 
=  AF_INET;
    listenAddr.sin_addr.s_addr 
=  htonl(INADDR_ANY);
    listenAddr.sin_port 
=  htons(LISTEN_PORT);

    
if (bind(sockListen, (SOCKADDR * ) & listenAddr,  sizeof (listenAddr))  ==  SOCKET_ERROR)
    {
        printf(
" bind() failed, error:%d.\n " , WSAGetLastError());
        closesocket(sockListen);
        WSACleanup();
        
return   1 ;
    }
    
else
        printf(
" bind()is fine!\n " );

    
if (listen(sockListen,  5 ==  SOCKET_ERROR)
    {
        printf(
" listen() failed, error:%d.\n " , WSAGetLastError());
        closesocket(sockListen);
        WSACleanup();
        
return   1 ;
    }
    
else
    {
        printf(
" listen() is OK! " );
    }

    
while (TRUE)
    {
        
if ((acceptSock  =  WSAAccept(sockListen, NULL, NULL, NULL,  0 ))  ==  SOCKET_ERROR)
        {
            printf(
" WSAAccept() failed, error:%d.\n " , WSAGetLastError());
            WSACleanup();
            
return   1 ;
        }
        
else
        {
            printf(
" WSAAccept() is OK!.\n " );
        }

        
if ((perHandleData  =  (LPPER_HANDLE_DATA)GlobalAlloc(GPTR,  sizeof (PER_HANDLE_DATA)))  ==  NULL)
        {
            printf(
" GlobalAlloc() failed, error:%d.\n " , GetLastError());
            WSACleanup();
            
return   1 ;
        }
        
else
        {
            printf(
" GlobalAlloc() for PER_HANDLE_DATA is OK!.\n " );
        }

        printf(
" socket %d create.\n " , acceptSock);        
        perHandleData
-> sock  =  acceptSock;

        
if (CreateIoCompletionPort((HANDLE)acceptSock, hCompletionPort, (DWORD)perHandleData,  0 ==  NULL)
        {
            printf(
" CreateIoCompletionPort() failed, error:%d.\n " , GetLastError());
            
return   1 ;
        }
        
else
        {
            printf(
" CreateIoCompletionPort() is OK!.\n " );
        }

        
if ((lpPerIoOperationData  =  (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR,  sizeof (PER_IO_OPERATION_DATA)))  ==  NULL)
        {
            printf(
" GlobalAlloc() failed, error:%d.\n " , GetLastError());
            
return   1 ;
        }
        
else
        {
            printf(
" GlobalAlloc() for PER_IO_OPERATION_DATA is OK!\n " );
        }

        ZeroMemory(
& (lpPerIoOperationData -> wsaOverlapped),  sizeof (OVERLAPPED));
        lpPerIoOperationData
-> wsaBuf.len  =  DATA_BUFSIZE;
        lpPerIoOperationData
-> wsaBuf.buf  =  lpPerIoOperationData -> buffer;

        dwFlags 
=   0 ;
        
if (WSARecv(acceptSock,  & (lpPerIoOperationData -> wsaBuf),  1 & dwBytesRecv,  & dwFlags,  & (lpPerIoOperationData -> wsaOverlapped), NULL)  ==  SOCKET_ERROR)
        {
            
if (WSAGetLastError()  !=  ERROR_IO_PENDING)
            {
                printf(
" WSARecv() failed, error %d\n " , WSAGetLastError());
                WSACleanup();
                
return   1 ;
            }
        }
        
else
        {
            printf(
" WSARecv() is OK!\n " );
        }
    }

    
if (WSACleanup()  ==  SOCKET_ERROR)
    {
        printf(
" WSACleanup() failed, error:%d.\n " , WSAGetLastError());
    }
    
else
    {
        printf(
" WSACleanup() is OK!.\n " );
    }
}

DWORD WINAPI ServerWorkerThread(LPVOID lpCompletionPortID)
{
    HANDLE hCompletionPort 
=  (HANDLE)lpCompletionPortID;
    DWORD dwBytesTransferred 
=   0 ;
    LPPER_HANDLE_DATA lpPerHandleData;
    LPPER_IO_OPERATION_DATA lpPerIoData;
    DWORD dwFlags;

    
while (TRUE)
    {
        
if (GetQueuedCompletionStatus(hCompletionPort,  & dwBytesTransferred,
            (DWORD
* ) & lpPerHandleData, (LPOVERLAPPED * ) & lpPerIoData, INFINITE)  ==   0 )
        {
            printf(
" GetQueuedCompletionStatus() failed, error:%d.\n " , GetLastError());
            
return   0 ;
        }
        
else
        {
            printf(
" GetQueuedCompletionStatus() is OK!.\n " );
        }

        
if (dwBytesTransferred  ==   0 )
        {
            printf(
" closing socket %d.\n " , lpPerHandleData);
            
if (closesocket(lpPerHandleData -> sock)  ==  SOCKET_ERROR)
            {
                printf(
" closesocket() failed with error %d\n " , WSAGetLastError());
                
return   0 ;
            }
            
else
                printf(
" closesocket() is fine!\n " );

            GlobalFree(lpPerHandleData);
            GlobalFree(lpPerIoData);
            
continue ;
        }
        
else
        {
            printf(
" %s " , lpPerIoData -> buffer);

            ZeroMemory(
& (lpPerIoData -> wsaOverlapped),  sizeof (OVERLAPPED));
            lpPerIoData
-> wsaBuf.len  =  DATA_BUFSIZE;
            lpPerIoData
-> wsaBuf.buf  =  lpPerIoData -> buffer;

            dwFlags 
=   0 ;
            
if (WSARecv(lpPerHandleData -> sock,  & (lpPerIoData -> wsaBuf),  1 & dwBytesTransferred,  & dwFlags,  & (lpPerIoData -> wsaOverlapped), NULL)  ==  SOCKET_ERROR)
            {
                
if (WSAGetLastError()  !=  ERROR_IO_PENDING)
                {
                    printf(
" WSARecv() failed, error %d\n " , WSAGetLastError());
                    
return   1 ;
                }
            }
            
else
            {
                printf(
" WSARecv() is OK!\n " );
            }
        }
    }
}

你可能感兴趣的:(Windows网络编程:使用Completion Port)