wsasend lpnumberofbytesSent

时间:2017-12-20 02:28:33

标签: visual-c++ iocp overlapped-io

我在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是不同的。 我不知道为什么。

1 个答案:

答案 0 :(得分:0)

仅在操作完成时从驱动程序返回的实际传输字节数。 io子系统将此值复制到传输到io操作的IO_STATUS_BLOCK.Information。结果用户得到这个值。但当然只有在手术完成后。

win32 api使用OVERLAPPED到位IO_STATUS_BLOCK - 将cast OVERLAPPED重新解释为IO_STATUS_BLOCK并将此指针传递给内核。所以InternalHigh将包含实际传输的字节数,但只有在完成操作后才会完成(如果错误同步返回 - io子系统不填充此字段,那么它在错误时值未定义。当然感觉为0)。

WSASendOVERLAPPED.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
  • 如果你使用自己的 IOCP GetQueuedCompletionStatus - 你得到了 返回指向调用lpOverlapped时使用的 WSASend 的指针(或 另一个io功能 - 这已经是你的任务决定了 操作完成后,此 lpOverlapped 使用的位置。在 这一点,您可以为此致电GetOverlappedResult lpOverlapped bWait 您可以设置为任何值 - 无关紧要,因为操作已经完成 - api将返回 马上在任何情况下都没有等待)你得到的实际数量 转移 lpNumberOfBytesTransferred 中的字节。然而 GetOverlappedResult只需复制 lpOverlapped->InternalHigh 即可 值为*lpNumberOfBytesTransferred所以你可以指导, 您自己使用InternalHigh而无需致电GetOverlappedResult