完成端口模型实例

来源:互联网 发布:沧州电脑网络销售培训 编辑:程序博客网 时间:2024/05/17 03:36

                                                                       完成端口模型实例

/*
 WinSock I/O Module
  ---Completion Port Module
 Server Example 1.0  
 */
#include <winsock2.h>
#include <mswsock.h>
#include <iostream.h>
#include <conio.h>

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

HANDLE hIocp;
SOCKET Listen;

//
//
自定义结构完成键”(单句柄数据)
//
typedef struct _PER_HANDLE_CONTEXT
{
 SOCKET                     client;
 _PER_HANDLE_CONTEXT*       pNext;
}PER_HANDLE_CONTEXT, *PPER_HANDLE_CONTEXT;

#define    BUFFER_SIZE           4096

typedef enum _IO_OPERATION
{
  RECV = 1, 
  SEND
}IO_OPERATION, *PIO_OPERATION;

typedef struct _PER_IO_CONTEXT
{
 WSAOVERLAPPED              ol;
 WSABUF                     wsaBuffer;
 CHAR                       szBuffer[BUFFER_SIZE];
 IO_OPERATION               OpType;
 _PER_IO_CONTEXT*           pNext;
}PER_IO_CONTEXT, *PPER_IO_CONTEXT;

DWORD WINAPI CompletionRoutine(LPVOID lpParam);
DWORD WINAPI ThreadAccept(LPVOID lpParam);

char sendBuffer[] = "/t Welcome to Completion Port IO Module server/r/n";

void main()
{
 WSADATA wsaData;
 int nRet;
 HANDLE hThread;
 
 nRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
 if(nRet != 0)
 {
  cout <<"WSAStartup Failed: " <<WSAGetLastError() <<endl;
  return;
 }

 hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
 if (NULL == hIocp)
 {
  cout <<"CreateIoCompletionPort Failed: " <<GetLastError() <<endl;
  WSACleanup();
  return;
 }
 
 SYSTEM_INFO SysInfo;
 GetSystemInfo(&SysInfo);
 for (int i=0; i<(int)SysInfo.dwNumberOfProcessors; i++)
 {
  hThread = CreateThread(NULL, 0, CompletionRoutine, NULL, 0, NULL);
  if(NULL == hThread)
  {
   cout <<"CreateThread Failed: " <<GetLastError() <<endl;
   WSACleanup();
   CloseHandle(hIocp);
   return;
  }
  CloseHandle(hThread);
 }
 
 Listen = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
 
    if (INVALID_SOCKET == Listen)
    {
  cout <<"WSASocket Failed: " <<WSAGetLastError() <<endl;
        WSACleanup();
        PostQueuedCompletionStatus(hIocp, 0, NULL, NULL);
        CloseHandle(hIocp);
        return;
    }
   
    SOCKADDR_IN inAddr;
   
    inAddr.sin_family = AF_INET;
 inAddr.sin_addr.s_addr = htonl(INADDR_ANY);
 inAddr.sin_port = htons(5150);  

    nRet = bind(Listen, (PSOCKADDR)&inAddr, sizeof(inAddr));

    if (SOCKET_ERROR == nRet)
    {
  closesocket(Listen);
  cout <<"bind Failed: " <<WSAGetLastError() <<endl;
  WSACleanup();
  PostQueuedCompletionStatus(hIocp, 0, NULL, NULL);
  CloseHandle(hIocp);
        return;
    } 

 nRet = listen(Listen, 20);
 
    if (SOCKET_ERROR == nRet)
    {
  closesocket(Listen);
  cout <<"listen Failed: " <<WSAGetLastError() <<endl;
        WSACleanup();
        PostQueuedCompletionStatus(hIocp, 0, NULL, NULL);
        CloseHandle(hIocp);
        return;
    } 
     
 hThread = CreateThread(NULL, 0, ThreadAccept, NULL, 0, NULL);
 if(NULL == hThread)
 {
  closesocket(Listen);
  cout <<"CreateThread Failed: " <<GetLastError() <<endl;
        WSACleanup();
        PostQueuedCompletionStatus(hIocp, 0, NULL, NULL);
        CloseHandle(hIocp);
        return;
    }
    CloseHandle(hThread);
    cout <<"Enter 'q' to exit: " <<endl;
    while(getch() != 'q');
    closesocket(Listen);
    WSACleanup();
    PostQueuedCompletionStatus(hIocp, 0, NULL, NULL);
    CloseHandle(hIocp);
 cout <<"Main thread will exit " <<endl;
 getch();
}

DWORD WINAPI ThreadAccept(LPVOID lpParam)
{
 SOCKET client;
 PPER_HANDLE_CONTEXT pHContext;
 HANDLE hRet;
 PPER_IO_CONTEXT pIContext;
 int nRet;
 
 while(true)
 {
  client = WSAAccept(Listen, NULL, NULL, NULL, 0);
  
  if(client == INVALID_SOCKET)
  {
   cout <<"WSAAccept Failed: " <<WSAGetLastError() <<endl;
   cout <<"ThreadAccept thread exit " <<endl;
         return 0;
        }
  pHContext = (PPER_HANDLE_CONTEXT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(PER_HANDLE_CONTEXT));
  if(NULL == pHContext)
  {
   cout <<"HeapAlloc Failed: " <<GetLastError() <<endl;
   closesocket(client);
   continue;
  }
  pHContext->client = client;
  pHContext->pNext = NULL;
  hRet = CreateIoCompletionPort((HANDLE)client, hIocp, (ULONG_PTR)pHContext, 0);
  if(NULL == hRet)
  {
   cout <<"CreateIoCompletionPort Failed: " <<GetLastError() <<endl;
   closesocket(client);
   HeapFree(GetProcessHeap(), 0, pHContext);
   continue;
  }
  pIContext = (PPER_IO_CONTEXT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PER_IO_CONTEXT));
  if(NULL == pIContext)
  {
   cout <<"HeapAlloc Failed: " <<GetLastError() <<endl;
   closesocket(client);
   HeapFree(GetProcessHeap(), 0, pHContext);
   continue;
  }
  ZeroMemory(&(pIContext->ol), sizeof(pIContext->ol));
  ZeroMemory(pIContext->szBuffer, BUFFER_SIZE);
  pIContext->wsaBuffer.buf = pIContext->szBuffer;
  pIContext->wsaBuffer.len = BUFFER_SIZE;
  pIContext->OpType = RECV;
  pIContext->pNext = NULL;
  
  DWORD nRecv = 0;
  DWORD nFlag = 0;

  nRet = WSARecv(pHContext->client, &(pIContext->wsaBuffer), 1, &nRecv, &nFlag, &(pIContext->ol), NULL);
  if(SOCKET_ERROR == nRet)
  {
   if(ERROR_IO_PENDING != WSAGetLastError())
   {
    cout <<"WSARecv Failed: " <<WSAGetLastError() <<endl;
    closesocket(pHContext->client);
    HeapFree(GetProcessHeap(), 0, pHContext);
    HeapFree(GetProcessHeap(), 0, pIContext);
    continue;
   }
  }
  
  ZeroMemory(&(pIContext->ol), sizeof(pIContext->ol));
  pIContext->wsaBuffer.buf = sendBuffer;
  pIContext->wsaBuffer.len = strlen(sendBuffer);
  pIContext->OpType = SEND;
  pIContext->pNext = NULL;
  
  DWORD nSend = 0;
  nFlag = 0;
  nRet = WSASend(pHContext->client, &(pIContext->wsaBuffer), 1, &nSend, nFlag, &(pIContext->ol), NULL);
  if(SOCKET_ERROR == nRet)
  {
   if(ERROR_IO_PENDING != WSAGetLastError())
   {
    cout <<"WSASend Failed: " <<WSAGetLastError() <<endl;
    closesocket(pHContext->client);
    HeapFree(GetProcessHeap(), 0, pHContext);
    HeapFree(GetProcessHeap(), 0, pIContext);
    continue;
   }
  }
  cout <<"Client connected with socket: " <<pHContext->client <<endl;
 }
}

DWORD WINAPI CompletionRoutine(LPVOID lpParam)
{
 DWORD dwBytes;
 PPER_HANDLE_CONTEXT pHContext = NULL;
 PPER_IO_CONTEXT pIContext = NULL;
 LPWSAOVERLAPPED pOL = NULL;
 int nRet;
 BOOL bRet;
 while(true)
 {
  bRet = GetQueuedCompletionStatus(hIocp, &dwBytes,(PULONG_PTR )&pHContext, &pOL, INFINITE);
  if(FALSE == bRet)
  {
   cout <<"GetQueuedCompletionStatus Failed: " <<GetLastError() <<endl;
   if((NULL != pOL) && (0 == dwBytes))
   {
    closesocket(pHContext->client);
    cout <<"Client disconnected socket: " <<pHContext->client <<endl;
    HeapFree(GetProcessHeap(), 0, pHContext);
    HeapFree(GetProcessHeap(), 0, CONTAINING_RECORD(pOL, PER_IO_CONTEXT, ol));
   }
   continue;
  }
  if(NULL == pHContext)
  {
   cout <<"CompletionRoutine thread exit " <<endl;
   return 0;
  }
  
  pIContext = CONTAINING_RECORD(pOL, PER_IO_CONTEXT, ol);
  
  if(0 == dwBytes)
  {
   closesocket(pHContext->client);
   cout <<"Client disconnected socket: " <<pHContext->client <<endl;
   HeapFree(GetProcessHeap(), 0, pHContext);
   HeapFree(GetProcessHeap(), 0, pIContext);
   continue;
  }
  
  switch(pIContext->OpType)
  {
   case RECV:
    cout << "Recv: " << pIContext->szBuffer << endl; 
    break;
   case SEND:
    cout << "Send: " << pIContext->wsaBuffer.buf << endl; 
    break;
   default:
    break;
  }
  
  ZeroMemory(&(pIContext->ol), sizeof(pIContext->ol));
  ZeroMemory(pIContext->szBuffer, BUFFER_SIZE);
  pIContext->wsaBuffer.buf = pIContext->szBuffer;
  pIContext->wsaBuffer.len = BUFFER_SIZE;
  pIContext->OpType = RECV;
  pIContext->pNext = NULL;
  
  DWORD nRecv = 0;
  DWORD nFlag = 0;

  nRet = WSARecv(pHContext->client, &(pIContext->wsaBuffer), 1, &nRecv, &nFlag, &(pIContext->ol), NULL);
  if(SOCKET_ERROR == nRet)
  {
   if(ERROR_IO_PENDING != WSAGetLastError())
   {
    cout <<"WSARecv Failed: " <<WSAGetLastError() <<endl;
    closesocket(pHContext->client);
    HeapFree(GetProcessHeap(), 0, pHContext);
    HeapFree(GetProcessHeap(), 0, pIContext);
    continue;
   }
  }
 }
}

 

 

原创粉丝点击