首页 > 未分类 > iocp进行SOCKET通信(转载)
2019
11-29

iocp进行SOCKET通信(转载)

当然TCP方式的模型还有事件选择模型。
就是把所有的网络事件和我们的一个程序里定义的事件梆定。
这个有它的好处,可能可以让我们更好的写一个线程来管理
接收与发送。
现在来讲一下一个完成端口模型。

  完成端口
 
一个完成端口其实就是一个通知队列,由操作系统把已经完成的重叠I/O请求的通知
放入其中。当某项I/O操作一旦完成,某个可以对该操作结果进行处理的工作者线程
就会收到一则通知。而套接字在被创建后,可以在任何时候与某个完成端口进行关
联。
 
步骤:
1、创建一个空的完成端口;
2、得到本地机器的CPU个数;
3、开启CPU*2个工作线程(又名线程池),全部都在等待完成端口的完成包;
4、创建TCP的监听socket,使用事件邦定,创建监听线程;
5、当有人连接进入的时候,将Client socket保存到一个我们自己定义的关键键,
    并把它与我们创建的完成端口关联;
6、使用WSARecv和WSASend函数投递一些请求,这是使用重叠I/O的方式;
7、重复5~6;

注:1、重叠I/O的方式中,接收与发送数据包的时候,一定要进行投递请求这是
   它们这个体系结构的特点
   当然,在完成端口方式中,不是直接使用的WSARecv和WSASend函数进行请求
   的投递的。而是使用的ReadFile,Write的方式
  2、完成端口使用了系统内部的一些模型,所以我们只要按照一定的顺序调用就
   可以完成了。
  3、完成端口是使用在这样的情况下,有成千上万的用户连接的时候,它能够
   保证性能不会降低。

 

iocp进行SOCKET通信(转载) - 第1张  | 逗分享开发经验 #include < winsock2.h >
iocp进行SOCKET通信(转载) - 第2张  | 逗分享开发经验#include
< windows.h >
iocp进行SOCKET通信(转载) - 第3张  | 逗分享开发经验#include
< stdio.h >
iocp进行SOCKET通信(转载) - 第4张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第5张  | 逗分享开发经验
#define PORT 5150
iocp进行SOCKET通信(转载) - 第6张  | 逗分享开发经验
#define DATA_BUFSIZE 8192
iocp进行SOCKET通信(转载) - 第7张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第8张  | 逗分享开发经验
// 关键项
iocp进行SOCKET通信(转载) - 第9张  | 逗分享开发经验
typedef struct
iocp进行SOCKET通信(转载) - 第10张  | 逗分享开发经验
{
iocp进行SOCKET通信(转载) - 第13张  | 逗分享开发经验   OVERLAPPED Overlapped;
iocp进行SOCKET通信(转载) - 第14张  | 逗分享开发经验   WSABUF DataBuf;
iocp进行SOCKET通信(转载) - 第15张  | 逗分享开发经验   CHAR Buffer[DATA_BUFSIZE];
iocp进行SOCKET通信(转载) - 第16张  | 逗分享开发经验   DWORD BytesSEND;
iocp进行SOCKET通信(转载) - 第17张  | 逗分享开发经验   DWORD BytesRECV;
iocp进行SOCKET通信(转载) - 第18张  | 逗分享开发经验}
PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;
iocp进行SOCKET通信(转载) - 第19张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第20张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第21张  | 逗分享开发经验typedef
struct  
iocp进行SOCKET通信(转载) - 第22张  | 逗分享开发经验
{
iocp进行SOCKET通信(转载) - 第25张  | 逗分享开发经验   SOCKET Socket;
iocp进行SOCKET通信(转载) - 第26张  | 逗分享开发经验}
PER_HANDLE_DATA, * LPPER_HANDLE_DATA;
iocp进行SOCKET通信(转载) - 第27张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第28张  | 逗分享开发经验DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);
iocp进行SOCKET通信(转载) - 第29张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第30张  | 逗分享开发经验
void main( void )
iocp进行SOCKET通信(转载) - 第31张  | 逗分享开发经验
{
iocp进行SOCKET通信(转载) - 第34张  | 逗分享开发经验   SOCKADDR_IN InternetAddr;
iocp进行SOCKET通信(转载) - 第35张  | 逗分享开发经验   SOCKET Listen;
iocp进行SOCKET通信(转载) - 第36张  | 逗分享开发经验   SOCKET Accept;
iocp进行SOCKET通信(转载) - 第37张  | 逗分享开发经验   HANDLE CompletionPort;
iocp进行SOCKET通信(转载) - 第38张  | 逗分享开发经验   SYSTEM_INFO SystemInfo;
iocp进行SOCKET通信(转载) - 第39张  | 逗分享开发经验   LPPER_HANDLE_DATA PerHandleData;
iocp进行SOCKET通信(转载) - 第40张  | 逗分享开发经验   LPPER_IO_OPERATION_DATA PerIoData;
iocp进行SOCKET通信(转载) - 第41张  | 逗分享开发经验  
int i;
iocp进行SOCKET通信(转载) - 第42张  | 逗分享开发经验   DWORD RecvBytes;
iocp进行SOCKET通信(转载) - 第43张  | 逗分享开发经验   DWORD Flags;
iocp进行SOCKET通信(转载) - 第44张  | 逗分享开发经验   DWORD ThreadID;
iocp进行SOCKET通信(转载) - 第45张  | 逗分享开发经验   WSADATA wsaData;
iocp进行SOCKET通信(转载) - 第46张  | 逗分享开发经验   DWORD Ret;
iocp进行SOCKET通信(转载) - 第47张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第48张  | 逗分享开发经验  
if ((Ret = WSAStartup( 0x0202 , & wsaData)) !=   0 )
iocp进行SOCKET通信(转载) - 第49张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第52张  | 逗分享开发经验      printf(
" WSAStartup failed with error %d\n " , Ret);
iocp进行SOCKET通信(转载) - 第53张  | 逗分享开发经验     
return ;
iocp进行SOCKET通信(转载) - 第54张  | 逗分享开发经验   }

iocp进行SOCKET通信(转载) - 第55张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第56张  | 逗分享开发经验  
// 打开一个空的完成端口
iocp进行SOCKET通信(转载) - 第57张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第58张  | 逗分享开发经验  
if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0 , 0 )) == NULL)
iocp进行SOCKET通信(转载) - 第59张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第62张  | 逗分享开发经验      printf(
" CreateIoCompletionPort failed with error: %d\n " , GetLastError());
iocp进行SOCKET通信(转载) - 第63张  | 逗分享开发经验     
return ;
iocp进行SOCKET通信(转载) - 第64张  | 逗分享开发经验   }

iocp进行SOCKET通信(转载) - 第65张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第66张  | 逗分享开发经验  
// Determine how many processors are on the system.
iocp进行SOCKET通信(转载) - 第67张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第68张  | 逗分享开发经验   GetSystemInfo(
& SystemInfo);
iocp进行SOCKET通信(转载) - 第69张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第70张  | 逗分享开发经验  
// 开启cpu个数的2倍个的线程
iocp进行SOCKET通信(转载) - 第71张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第72张  | 逗分享开发经验  
for (i =   0 ; i < SystemInfo.dwNumberOfProcessors *   2 ; i ++ )
iocp进行SOCKET通信(转载) - 第73张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第76张  | 逗分享开发经验      HANDLE ThreadHandle;
iocp进行SOCKET通信(转载) - 第77张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第78张  | 逗分享开发经验     
// Create a server worker thread and pass the completion port to the thread.
iocp进行SOCKET通信(转载) - 第79张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第80张  | 逗分享开发经验     
if ((ThreadHandle = CreateThread(NULL, 0 , ServerWorkerThread, CompletionPort,
iocp进行SOCKET通信(转载) - 第81张  | 逗分享开发经验        
0 , & ThreadID)) == NULL)
iocp进行SOCKET通信(转载) - 第82张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第85张  | 逗分享开发经验         printf(
" CreateThread() failed with error %d\n " , GetLastError());
iocp进行SOCKET通信(转载) - 第86张  | 逗分享开发经验        
return ;
iocp进行SOCKET通信(转载) - 第87张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第88张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第89张  | 逗分享开发经验     
// Close the thread handle
iocp进行SOCKET通信(转载) - 第90张  | 逗分享开发经验
      CloseHandle(ThreadHandle);
iocp进行SOCKET通信(转载) - 第91张  | 逗分享开发经验   }

iocp进行SOCKET通信(转载) - 第92张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第93张  | 逗分享开发经验  
// 打开一个服务器socket
iocp进行SOCKET通信(转载) - 第94张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第95张  | 逗分享开发经验  
if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0 , NULL, 0 ,
iocp进行SOCKET通信(转载) - 第96张  | 逗分享开发经验      WSA_FLAG_OVERLAPPED))
== INVALID_SOCKET)
iocp进行SOCKET通信(转载) - 第97张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第100张  | 逗分享开发经验      printf(
" WSASocket() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第101张  | 逗分享开发经验     
return ;
iocp进行SOCKET通信(转载) - 第102张  | 逗分享开发经验   }
 
iocp进行SOCKET通信(转载) - 第103张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第104张  | 逗分享开发经验   InternetAddr.sin_family
= AF_INET;
iocp进行SOCKET通信(转载) - 第105张  | 逗分享开发经验   InternetAddr.sin_addr.s_addr
= htonl(INADDR_ANY);
iocp进行SOCKET通信(转载) - 第106张  | 逗分享开发经验   InternetAddr.sin_port
= htons(PORT);
iocp进行SOCKET通信(转载) - 第107张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第108张  | 逗分享开发经验  
if (bind(Listen, (PSOCKADDR) & InternetAddr, sizeof (InternetAddr)) == SOCKET_ERROR)
iocp进行SOCKET通信(转载) - 第109张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第112张  | 逗分享开发经验      printf(
" bind() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第113张  | 逗分享开发经验     
return ;
iocp进行SOCKET通信(转载) - 第114张  | 逗分享开发经验   }

iocp进行SOCKET通信(转载) - 第115张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第116张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第117张  | 逗分享开发经验  
if (listen(Listen, 5 ) == SOCKET_ERROR)
iocp进行SOCKET通信(转载) - 第118张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第121张  | 逗分享开发经验      printf(
" listen() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第122张  | 逗分享开发经验     
return ;
iocp进行SOCKET通信(转载) - 第123张  | 逗分享开发经验   }

iocp进行SOCKET通信(转载) - 第124张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第125张  | 逗分享开发经验  
// 开始接收从客户端来的连接
iocp进行SOCKET通信(转载) - 第126张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第127张  | 逗分享开发经验  
while (TRUE)
iocp进行SOCKET通信(转载) - 第128张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第131张  | 逗分享开发经验     
if ((Accept = WSAAccept(Listen, NULL, NULL, NULL, 0 )) == SOCKET_ERROR)
iocp进行SOCKET通信(转载) - 第132张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第135张  | 逗分享开发经验         printf(
" WSAAccept() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第136张  | 逗分享开发经验        
return ;
iocp进行SOCKET通信(转载) - 第137张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第138张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第139张  | 逗分享开发经验     
// 创建一个关键项用于保存这个客户端的信息,用户接收发送的重叠结构,
iocp进行SOCKET通信(转载) - 第140张  | 逗分享开发经验     
// 还有使用到的缓冲区
iocp进行SOCKET通信(转载) - 第141张  | 逗分享开发经验
      if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,
iocp进行SOCKET通信(转载) - 第142张  | 逗分享开发经验        
sizeof (PER_HANDLE_DATA))) == NULL)
iocp进行SOCKET通信(转载) - 第143张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第146张  | 逗分享开发经验         printf(
" GlobalAlloc() failed with error %d\n " , GetLastError());
iocp进行SOCKET通信(转载) - 第147张  | 逗分享开发经验        
return ;
iocp进行SOCKET通信(转载) - 第148张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第149张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第150张  | 逗分享开发经验     
// Associate the accepted socket with the original completion port.
iocp进行SOCKET通信(转载) - 第151张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第152张  | 逗分享开发经验      printf(
" Socket number %d connected\n " , Accept);
iocp进行SOCKET通信(转载) - 第153张  | 逗分享开发经验      PerHandleData
-> Socket = Accept;
iocp进行SOCKET通信(转载) - 第154张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第155张  | 逗分享开发经验     
// 与我们的创建的那个完成端口关联起来,将关键项也与指定的一个完成端口关联
iocp进行SOCKET通信(转载) - 第156张  | 逗分享开发经验
      if (CreateIoCompletionPort((HANDLE) Accept, CompletionPort, (DWORD) PerHandleData,
iocp进行SOCKET通信(转载) - 第157张  | 逗分享开发经验        
0 ) == NULL)
iocp进行SOCKET通信(转载) - 第158张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第161张  | 逗分享开发经验         printf(
" CreateIoCompletionPort failed with error %d\n " , GetLastError());
iocp进行SOCKET通信(转载) - 第162张  | 逗分享开发经验        
return ;
iocp进行SOCKET通信(转载) - 第163张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第164张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第165张  | 逗分享开发经验     
// 投递一次接收,由于接收都需要使用这个函数来投递一个接收的准备
iocp进行SOCKET通信(转载) - 第166张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第167张  | 逗分享开发经验     
if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,          sizeof (PER_IO_OPERATION_DATA))) == NULL)
iocp进行SOCKET通信(转载) - 第168张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第171张  | 逗分享开发经验         printf(
" GlobalAlloc() failed with error %d\n " , GetLastError());
iocp进行SOCKET通信(转载) - 第172张  | 逗分享开发经验        
return ;
iocp进行SOCKET通信(转载) - 第173张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第174张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第175张  | 逗分享开发经验      ZeroMemory(
& (PerIoData -> Overlapped), sizeof (OVERLAPPED));
iocp进行SOCKET通信(转载) - 第176张  | 逗分享开发经验      PerIoData
-> BytesSEND =   0 ;
iocp进行SOCKET通信(转载) - 第177张  | 逗分享开发经验      PerIoData
-> BytesRECV =   0 ;
iocp进行SOCKET通信(转载) - 第178张  | 逗分享开发经验      PerIoData
-> DataBuf.len = DATA_BUFSIZE;
iocp进行SOCKET通信(转载) - 第179张  | 逗分享开发经验      PerIoData
-> DataBuf.buf = PerIoData -> Buffer;
iocp进行SOCKET通信(转载) - 第180张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第181张  | 逗分享开发经验      Flags
=   0 ;
iocp进行SOCKET通信(转载) - 第182张  | 逗分享开发经验     
if (WSARecv(Accept, & (PerIoData -> DataBuf), 1 , & RecvBytes, & Flags,
iocp进行SOCKET通信(转载) - 第183张  | 逗分享开发经验        
& (PerIoData -> Overlapped), NULL) == SOCKET_ERROR)
iocp进行SOCKET通信(转载) - 第184张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第187张  | 逗分享开发经验        
if (WSAGetLastError() != ERROR_IO_PENDING)
iocp进行SOCKET通信(转载) - 第188张  | 逗分享开发经验        
{
iocp进行SOCKET通信(转载) - 第191张  | 逗分享开发经验            printf(
" WSARecv() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第192张  | 逗分享开发经验           
return ;
iocp进行SOCKET通信(转载) - 第193张  | 逗分享开发经验         }

iocp进行SOCKET通信(转载) - 第194张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第195张  | 逗分享开发经验   }

iocp进行SOCKET通信(转载) - 第196张  | 逗分享开发经验}

iocp进行SOCKET通信(转载) - 第197张  | 逗分享开发经验
// 工作线程
iocp进行SOCKET通信(转载) - 第198张  | 逗分享开发经验
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
iocp进行SOCKET通信(转载) - 第199张  | 逗分享开发经验
{
iocp进行SOCKET通信(转载) - 第202张  | 逗分享开发经验   HANDLE CompletionPort
= (HANDLE) CompletionPortID;
iocp进行SOCKET通信(转载) - 第203张  | 逗分享开发经验   DWORD BytesTransferred;
iocp进行SOCKET通信(转载) - 第204张  | 逗分享开发经验   LPOVERLAPPED Overlapped;
iocp进行SOCKET通信(转载) - 第205张  | 逗分享开发经验   LPPER_HANDLE_DATA PerHandleData;
iocp进行SOCKET通信(转载) - 第206张  | 逗分享开发经验   LPPER_IO_OPERATION_DATA PerIoData;
iocp进行SOCKET通信(转载) - 第207张  | 逗分享开发经验   DWORD SendBytes, RecvBytes;
iocp进行SOCKET通信(转载) - 第208张  | 逗分享开发经验   DWORD Flags;
iocp进行SOCKET通信(转载) - 第209张  | 逗分享开发经验  
iocp进行SOCKET通信(转载) - 第210张  | 逗分享开发经验  
while (TRUE)
iocp进行SOCKET通信(转载) - 第211张  | 逗分享开发经验  
{
iocp进行SOCKET通信(转载) - 第214张  | 逗分享开发经验     
// 完成端口有消息来了
iocp进行SOCKET通信(转载) - 第215张  | 逗分享开发经验
      if (GetQueuedCompletionStatus(CompletionPort, & BytesTransferred,
iocp进行SOCKET通信(转载) - 第216张  | 逗分享开发经验         (LPDWORD)
& PerHandleData, (LPOVERLAPPED * ) & PerIoData, INFINITE) ==   0 )
iocp进行SOCKET通信(转载) - 第217张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第220张  | 逗分享开发经验         printf(
" GetQueuedCompletionStatus failed with error %d\n " , GetLastError());
iocp进行SOCKET通信(转载) - 第221张  | 逗分享开发经验        
return   0 ;
iocp进行SOCKET通信(转载) - 第222张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第223张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第224张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第225张  | 逗分享开发经验     
// 是不是有人退出了
iocp进行SOCKET通信(转载) - 第226张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第227张  | 逗分享开发经验     
if (BytesTransferred ==   0 )
iocp进行SOCKET通信(转载) - 第228张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第231张  | 逗分享开发经验         printf(
" Closing socket %d\n " , PerHandleData -> Socket);
iocp进行SOCKET通信(转载) - 第232张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第233张  | 逗分享开发经验        
if (closesocket(PerHandleData -> Socket) == SOCKET_ERROR)
iocp进行SOCKET通信(转载) - 第234张  | 逗分享开发经验        
{
iocp进行SOCKET通信(转载) - 第237张  | 逗分享开发经验            printf(
" closesocket() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第238张  | 逗分享开发经验           
return   0 ;
iocp进行SOCKET通信(转载) - 第239张  | 逗分享开发经验         }

iocp进行SOCKET通信(转载) - 第240张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第241张  | 逗分享开发经验         GlobalFree(PerHandleData);
iocp进行SOCKET通信(转载) - 第242张  | 逗分享开发经验         GlobalFree(PerIoData);
iocp进行SOCKET通信(转载) - 第243张  | 逗分享开发经验        
continue ;
iocp进行SOCKET通信(转载) - 第244张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第245张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第246张  | 逗分享开发经验     
//
iocp进行SOCKET通信(转载) - 第247张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第248张  | 逗分享开发经验     
if (PerIoData -> BytesRECV ==   0 )
iocp进行SOCKET通信(转载) - 第249张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第252张  | 逗分享开发经验         PerIoData
-> BytesRECV = BytesTransferred;
iocp进行SOCKET通信(转载) - 第253张  | 逗分享开发经验         PerIoData
-> BytesSEND =   0 ;
iocp进行SOCKET通信(转载) - 第254张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第255张  | 逗分享开发经验     
else
iocp进行SOCKET通信(转载) - 第256张  | 逗分享开发经验      
{
iocp进行SOCKET通信(转载) - 第259张  | 逗分享开发经验         PerIoData
-> BytesSEND += BytesTransferred;
iocp进行SOCKET通信(转载) - 第260张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第261张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第262张  | 逗分享开发经验     
if (PerIoData -> BytesRECV > PerIoData -> BytesSEND)
iocp进行SOCKET通信(转载) - 第263张  | 逗分享开发经验     
{
iocp进行SOCKET通信(转载) - 第266张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第267张  | 逗分享开发经验        
// Post another WSASend() request.
iocp进行SOCKET通信(转载) - 第268张  | 逗分享开发经验        
// Since WSASend() is not gauranteed to send all of the bytes requested,
iocp进行SOCKET通信(转载) - 第269张  | 逗分享开发经验        
// continue posting WSASend() calls until all received bytes are sent.
iocp进行SOCKET通信(转载) - 第270张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第271张  | 逗分享开发经验         ZeroMemory(
& (PerIoData -> Overlapped), sizeof (OVERLAPPED));
iocp进行SOCKET通信(转载) - 第272张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第273张  | 逗分享开发经验         PerIoData
-> DataBuf.buf = PerIoData -> Buffer + PerIoData -> BytesSEND;
iocp进行SOCKET通信(转载) - 第274张  | 逗分享开发经验         PerIoData
-> DataBuf.len = PerIoData -> BytesRECV - PerIoData -> BytesSEND;
iocp进行SOCKET通信(转载) - 第275张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第276张  | 逗分享开发经验        
if (WSASend(PerHandleData -> Socket, & (PerIoData -> DataBuf), 1 , & SendBytes, 0 ,
iocp进行SOCKET通信(转载) - 第277张  | 逗分享开发经验           
& (PerIoData -> Overlapped), NULL) == SOCKET_ERROR)
iocp进行SOCKET通信(转载) - 第278张  | 逗分享开发经验        
{
iocp进行SOCKET通信(转载) - 第281张  | 逗分享开发经验           
if (WSAGetLastError() != ERROR_IO_PENDING)
iocp进行SOCKET通信(转载) - 第282张  | 逗分享开发经验           
{
iocp进行SOCKET通信(转载) - 第285张  | 逗分享开发经验               printf(
" WSASend() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第286张  | 逗分享开发经验              
return   0 ;
iocp进行SOCKET通信(转载) - 第287张  | 逗分享开发经验            }

iocp进行SOCKET通信(转载) - 第288张  | 逗分享开发经验         }

iocp进行SOCKET通信(转载) - 第289张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第290张  | 逗分享开发经验     
else
iocp进行SOCKET通信(转载) - 第291张  | 逗分享开发经验      
{
iocp进行SOCKET通信(转载) - 第294张  | 逗分享开发经验         PerIoData
-> BytesRECV =   0 ;
iocp进行SOCKET通信(转载) - 第295张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第296张  | 逗分享开发经验        
// Now that there are no more bytes to send post another WSARecv() request.
iocp进行SOCKET通信(转载) - 第297张  | 逗分享开发经验

iocp进行SOCKET通信(转载) - 第298张  | 逗分享开发经验         Flags
=   0 ;
iocp进行SOCKET通信(转载) - 第299张  | 逗分享开发经验         ZeroMemory(
& (PerIoData -> Overlapped), sizeof (OVERLAPPED));
iocp进行SOCKET通信(转载) - 第300张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第301张  | 逗分享开发经验         PerIoData
-> DataBuf.len = DATA_BUFSIZE;
iocp进行SOCKET通信(转载) - 第302张  | 逗分享开发经验         PerIoData
-> DataBuf.buf = PerIoData -> Buffer;
iocp进行SOCKET通信(转载) - 第303张  | 逗分享开发经验
iocp进行SOCKET通信(转载) - 第304张  | 逗分享开发经验        
if (WSARecv(PerHandleData -> Socket, & (PerIoData -> DataBuf), 1 , & RecvBytes, & Flags,
iocp进行SOCKET通信(转载) - 第305张  | 逗分享开发经验           
& (PerIoData -> Overlapped), NULL) == SOCKET_ERROR)
iocp进行SOCKET通信(转载) - 第306张  | 逗分享开发经验        
{
iocp进行SOCKET通信(转载) - 第309张  | 逗分享开发经验           
if (WSAGetLastError() != ERROR_IO_PENDING)
iocp进行SOCKET通信(转载) - 第310张  | 逗分享开发经验           
{
iocp进行SOCKET通信(转载) - 第313张  | 逗分享开发经验               printf(
" WSARecv() failed with error %d\n " , WSAGetLastError());
iocp进行SOCKET通信(转载) - 第314张  | 逗分享开发经验              
return   0 ;
iocp进行SOCKET通信(转载) - 第315张  | 逗分享开发经验            }

iocp进行SOCKET通信(转载) - 第316张  | 逗分享开发经验         }

iocp进行SOCKET通信(转载) - 第317张  | 逗分享开发经验      }

iocp进行SOCKET通信(转载) - 第318张  | 逗分享开发经验   }

iocp进行SOCKET通信(转载) - 第319张  | 逗分享开发经验}

iocp进行SOCKET通信(转载) - 第320张  | 逗分享开发经验
最后编辑:
作者:搬运工
这个作者貌似有点懒,什么都没有留下。