完成端口GetQueuedCompletionStatus后,我怎么知道是WSASend完成了?还是WSARecv完成了??
//关键项typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
DWORD BytesSEND;
DWORD BytesRECV;
} PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;
typedef struct
{
SOCKET Socket;
} PER_HANDLE_DATA, * LPPER_HANDLE_DATA;
假如我前面代码中WSASend和WSARecv都投递了
下面代码看不懂
//完成端口有消息来了
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
return 0;
}
//是不是有client退出了
if (BytesTransferred == 0)
{
//.....
continue;
}
//下面看不懂
if (PerIoData->BytesRECV == 0)
{
PerIoData->BytesRECV = BytesTransferred;
PerIoData->BytesSEND = 0;
}
else
{
PerIoData->BytesSEND += BytesTransferred;
} if (PerIoData->BytesRECV > PerIoData->BytesSEND)
{
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.buf = PerIoData->Buffer + PerIoData->BytesSEND;
PerIoData->DataBuf.len = PerIoData->BytesRECV - PerIoData->BytesSEND;
//关键项typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
DWORD BytesSEND;
DWORD BytesRECV;
} PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;
typedef struct
{
SOCKET Socket;
} PER_HANDLE_DATA, * LPPER_HANDLE_DATA;
假如我前面代码中WSASend和WSARecv都投递了
下面代码看不懂
//完成端口有消息来了
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
return 0;
}
//是不是有client退出了
if (BytesTransferred == 0)
{
//.....
continue;
}
//下面看不懂
if (PerIoData->BytesRECV == 0)
{
PerIoData->BytesRECV = BytesTransferred;
PerIoData->BytesSEND = 0;
}
else
{
PerIoData->BytesSEND += BytesTransferred;
} if (PerIoData->BytesRECV > PerIoData->BytesSEND)
{
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.buf = PerIoData->Buffer + PerIoData->BytesSEND;
PerIoData->DataBuf.len = PerIoData->BytesRECV - PerIoData->BytesSEND;
->
通常的办法是在PER_IO_OPERATION_DATA里面加一个变量 指明投递前的 类型.
如, int type; //0 for recv, 1 for send
那么你在投递WSASend 前 应该置type为1. 这样当你收到完成通知, 可以根据type来获知是send或recv.http://www.codeproject.com/internet/ 有很多完成端口的例子. 对此有详细的代码加以说明了.====你那个看不懂的代码 , 它的意图是服务器收到多少字节就在send多少字节, 所以它根据收到的字节数BytesRECV 是否为0 来判断之前投递的是读操作, 或写操作.
PerIOData->OPCode == IOCP_OP_RECV 表示接收
PerIOData->OPCode == IOCP_OP_ACCEPT
typedef struct
{
OVERLAPPED Overlapped;
IOCP_OP_CODE OPCode;
...
}PER_IO_OP_DATA, *LP_PER_IO_OP_DATA;
还有这个CompletionKey:SendPerIoData,我是把它定义为全局变量的。没办法,要线程间共用。不知道大家怎么处理?? if (WSASend(PerHandleData->Socket, &(SendPerIoData->DataBuf), 1, &SendBytes, Flags,
&(SendPerIoData->Overlapped), NULL) == SOCKET_ERROR)
并且把这个发送代码放在里面,一取到数据我就发
if (WSASend(PerHandleData->Socket, &(SendPerIoData->DataBuf), 1, &SendBytes, Flags,
&(SendPerIoData->Overlapped), NULL) == SOCKET_ERROR)我的问题是PerHandleData->Socket这个参数不就是CLIENT socket吗!!还有SendPerIoData结构体(里面放WSAOVERLAPPED的那个) 都该如何存放??