关闭

完成端口例子

标签: socketnulliostreamiowinapistruct
2220人阅读 评论(0) 收藏 举报
分类:

完成端口例子

                                      

 

#include "stdafx.h"

 

#include <iostream.h>

 

#include

 

#include

 

#include

 

 

#define PORT 5150

 

#define DATA_BUFSIZE 8192

 

 

typedef struct

 

{

 

  OVERLAPPED OVerlapped;

 

  WSABUF DATABuf;

 

  CHAR Buffer[DATA_BUFSIZE];

 

  DWORD BytesSend,BytesRecv;

 

}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;

 

 

typedef struct

 

 {

 

  SOCKET Socket;

 

}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;

 

 

 

DWORD WINAPI ServerWorkerThread(LPVOID ComlpetionPortID);

 

 

int main(int argc, char* argv[])

 

{

 

       SOCKADDR_IN InternetAddr;

 

  SOCKET Listen,Accept;

 

  HANDLE CompetionPort;

 

  SYSTEM_INFO SystenInfo;

 

  LPPER_HANDLE_DATA PerHandleData;

 

  LPPER_IO_OPERATION_DATA PerIOData;

 

  int i;

 

  DWORD RecvBytes;

 

  DWORD Flags;

 

  DWORD ThreadID;

 

  WSADATA wsadata;

 

  DWORD Ret;

 

 

 

  if (Ret = WSAStartup(0x2020,&wsadata) != 0)

 

  {

 

    printf("WSAStartup failed with error %d/n",Ret);

 

    return 0;

 

  }

 

 

 

   //打开一个空的完成端口

 

  if ((CompetionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0)) == NULL)

 

  {

 

    printf("CreateIoCompletionPort failed with error %d/n",GetLastError());

 

    return 0;

 

  }

 

 

 

  GetSystemInfo(&SystenInfo);

 

  

 

  // 开启cpu个数的2倍个的线程

 

  for (i=0; i < SystenInfo.dwNumberOfProcessors*2; i++)

 

  {

 

    HANDLE ThreadHandle;

 

    //创建服务器工作线程,并且向线程传送完成端口

 

    if ((ThreadHandle = CreateThread(NULL,0,ServerWorkerThread,CompetionPort,0,&ThreadID)) == NULL)

 

    {

 

      printf("CreateThread failed with error %d/n" ,GetLastError());

 

      return 0;

 

    }

 

    CloseHandle(ThreadHandle);

 

  }

 

 

 

  //打开一个服务器socket

 

  if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)

 

  {

 

    printf("WSASocket() failed with error %d/n", WSAGetLastError());

 

    return 0;

 

  }

 

 

 

  InternetAddr.sin_family = AF_INET;

 

  InternetAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

 

  InternetAddr.sin_port = htons(PORT);

 

 

 

  if (bind(Listen,(LPSOCKADDR)&InternetAddr,sizeof(InternetAddr)) == SOCKET_ERROR)

 

  {

 

    printf("bind failed with error %d/n",WSAGetLastError());

 

    return 0;

 

  }

 

 

  if (listen(Listen,5) == SOCKET_ERROR)

 

  {

 

    printf("listen failed with error %d/n",WSAGetLastError());

 

    return 0;

 

  }

 

 

  //接收连接并且分发给完成端口

 

  while (TRUE)

 

  {

 

    if ((Accept = WSAAccept(Listen,NULL,NULL,NULL,0)) == SOCKET_ERROR)

 

    {

 

      printf("WSAAccept failed with error %d/n",WSAGetLastError());

 

      return 0;

 

    }

 

 

    //创建与套接字相关的套接字信息结构

 

    if ((PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA))) == NULL)

 

    {

 

      printf("GlobalAlloc failed with error %d/n",GetLastError());

 

      return 0;

 

    }

 

   

 

    // Associate the accepted socket with the original completion port.

 

    printf("Socket number %d connected/n",Accept);

 

    PerHandleData->Socket = Accept;//结构中存入接收的套接字

 

   

 

    //与我们的创建的那个完成端口关联起来,将关键项也与指定的一个完成端口关联

 

    if ((CreateIoCompletionPort((HANDLE)Accept,CompetionPort,(DWORD)PerHandleData,0)) == NULL)

 

    {

 

      printf("CreateIoCompletionPort failed with error%d/n",GetLastError());

 

      return 0;

 

    }

 

 

    // 创建同下面的WSARecv调用相关的IO套接字信息结构体

 

    if ((PerIOData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA))) = NULL)

 

    {

 

      printf("GlobalAloc failed with error %d/n",GetLastError());

 

      return 0;

 

    }

 

    ZeroMemory(&(PerIOData->OVerlapped),sizeof(OVERLAPPED));

 

    PerIOData->BytesRecv = 0;

 

    PerIOData->BytesSend = 0;

 

    PerIOData->DATABuf.len = DATA_BUFSIZE;

 

    PerIOData->DATABuf.buf = PerIOData->Buffer;

 

    Flags = 0;

 

 

    if (WSARecv(Accept,&(PerIOData->DATABuf),1,&RecvBytes,&Flags,&(PerIOData->OVerlapped),NULL) == SOCKET_ERROR)

 

    {

 

     if (WSAGetLastError() != ERROR_IO_PENDING)

 

     {

 

       printf("WSARecv() failed with error %d/n",WSAGetLastError());

 

       return 0;

 

     }

 

    }

 

  }

 

  return 0;

 

}

 

 工作者线程见下文

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:188573次
    • 积分:2290
    • 等级:
    • 排名:第16988名
    • 原创:32篇
    • 转载:74篇
    • 译文:0篇
    • 评论:15条
    最新评论
    名家专栏