wsasend lpnumberofbytesSent
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wsasend lpnumberofbytesSent相关的知识,希望对你有一定的参考价值。
我在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是不同的。我不知道为什么。
仅当操作完成时,从驱动程序返回的实际传输字节数。 io子系统将此值复制到传输到io操作的IO_STATUS_BLOCK.Information
。结果用户得到这个值。但当然只有在手术完成后。
win32 api使用OVERLAPPED
到位IO_STATUS_BLOCK
- 重新解释将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完成时得到这个值。你如何得到它已经取决于你如何通知完成。
- 如果你使用
BindIoCompletionCallback
- 你在FileIOCompletionRoutine
的dwNumberOfBytesTransfered
论证中得到它 - 如果你使用
CreateThreadpoolIo
-你在IoCompletionCallback
的NumberOfBytesTransferred
论证中得到它 - 如果你使用自己的IOCP和
GetQueuedCompletionStatus
- 你得到了指向你的lpOverlapped
的指针,用于调用WSASend
(或其他一些io函数 - 这已经是你的任务决定了这个lpOverlapped
使用的地方)在操作完成后。在这一点上你可以调用GetOverlappedResult
这个lpOverlapped
(bWait
你可以设置为任何值 - 无关紧要因为操作已经完成 - api将在任何情况下立即返回而无需等待)并且你在lpNumberOfBytesTransferred
中获得了实际的传输字节数。然而GetOverlappedResult
只是将lpOverlapped->InternalHigh
值复制到*lpNumberOfBytesTransferred
所以你可以直接,自己使用InternalHigh
而不打电话给GetOverlappedResult
以上是关于wsasend lpnumberofbytesSent的主要内容,如果未能解决你的问题,请参考以下文章