完成端口例子

#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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值