我在IOCP结构化服务器上使用wsasend。 有一个问题。
wsabuf [bufcount - 1] .buf = pPacket-> GetPacketBufferPtr ();
wsabuf [bufcount - 1] .len = (int) pPacket-> Get_PacketSize ();
iSendSize + = wsabuf [bufcount - 1] .len;
bufcount ++;
int retval = WSASend (pSession-> socket, wsabuf, bufcount-1, & sendbytes,flag, & pSession-> overlapped_Send, NULL);
if (retval == SOCKET_ERROR)
{
if (WSAGetLastError ()! = WSA_IO_PENDING)
{
......
}
}
if (retval == 0)
{
if (sendbytes! = iSendSize)
{
........
}
}
.....
在上面的代码中,我将数据包保存到wsabuf并通过wsasend发送。 最后,我比较了sendbytes和iSendSize。 顺便说一句,sendbytes和iSendSize是不同的。 我不知道为什么。
答案 0 :(得分:0)
仅在操作完成时从驱动程序返回的实际传输字节数。 io子系统将此值复制到传输到io操作的IO_STATUS_BLOCK.Information
。结果用户得到这个值。但当然只有在手术完成后。
win32 api使用OVERLAPPED
到位IO_STATUS_BLOCK
- 将cast OVERLAPPED
重新解释为IO_STATUS_BLOCK
并将此指针传递给内核。所以InternalHigh
将包含实际传输的字节数,但只有在完成操作后才会完成(如果错误同步返回 - io子系统不填充此字段,那么它在错误时值未定义。当然感觉为0)。
WSASend
从OVERLAPPED.InternalHigh
获取值(在调用内核之后),如果lpNumberOfBytesSent
不是0,则将其复制到此处。如果你使用同步套接字句柄 - 此时io操作已经完成(io子系统内部等待这个,然后返回调用者),OVERLAPPED.InternalHigh
的有效值将被复制到*lpNumberOfBytesSent
看起来像
if (!lpOverlapped)
{
OVERLAPPED Overlapped = {};
lpOverlapped = &Overlapped;
}
ZwDeviceIoControlFile(.. reinterpret_cast<IO_STATUS_BLOCK*>(lpOverlapped) ..)
if (lpNumberOfBytesSent)
{
*lpNumberOfBytesSent = (ULONG)lpOverlapped->InternalHigh;
}
在异步套接字句柄的情况下,从内核返回后通常还没有完成操作。结果lpOverlapped->InternalHigh
但没有填充正确的字节数。和
*lpNumberOfBytesSent = (ULONG)lpOverlapped->InternalHigh;
得到错误(未定义,如果你和系统没有初始化,比如0)结果。
结论 - 您不能将sendbytes
用于异步io操作。这是什么未定义。当io完成时,您可以并且需要获得此值 。你如何得到它已经取决于你如何通知完成。
BindIoCompletionCallback
- 你就明白了
dwNumberOfBytesTransfered
中的FileIOCompletionRoutine
参数CreateThreadpoolIo
- 你就明白了
NumberOfBytesTransferred
参数IoCompletionCallback
GetQueuedCompletionStatus
- 你得到了
返回指向调用lpOverlapped
时使用的 WSASend
的指针(或
另一个io功能 - 这已经是你的任务决定了
操作完成后,此 lpOverlapped
使用的位置。在
这一点,您可以为此致电GetOverlappedResult
lpOverlapped
( bWait
您可以设置为任何值 - 无关紧要,因为操作已经完成 - api将返回
马上在任何情况下都没有等待)你得到的实际数量
转移 lpNumberOfBytesTransferred
中的字节。然而
GetOverlappedResult
只需复制 lpOverlapped->InternalHigh
即可
值为*lpNumberOfBytesTransferred
所以你可以指导,
您自己使用InternalHigh
而无需致电GetOverlappedResult