Visual c++ wsasend lpnumberofbytesSent

Visual c++ wsasend lpnumberofbytesSent,visual-c++,iocp,overlapped-io,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-&

我正在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操作。结果,用户返回该值。但当然只有在手术完成后

win32 api就地使用-将强制转换
OVERLAPPED
重新解释为
IO_STATUS_BLOCK
,并将此指针传递给内核。因此,
InternalHigh
将包含实际传输的字节数,但只有在操作完成后(在同步返回错误的情况下-io子系统未填充此字段,因此它的值在错误时未定义。当然是0)

WSASend
get value(在调用内核后)来自
OVERLAPPED.InternalHigh
和if
lpNumberOfBytesSent
not 0-将其复制到此处。如果您使用同步套接字句柄-此时io操作已经完成(io子系统内部等待,然后返回调用方),并且来自
的有效值重叠。InternalHigh
将复制到
*lpNumberOfBytesSent

在代码中,这将是

if (!lpOverlapped)
{
    OVERLAPPED Overlapped = {};
    lpOverlapped = &Overlapped;
}

ZwDeviceIoControlFile(.. reinterpret_cast<IO_STATUS_BLOCK*>(lpOverlapped) ..)

if (lpNumberOfBytesSent)
{
  *lpNumberOfBytesSent = (ULONG)lpOverlapped->InternalHigh;
}
得到了不正确的(未定义,如果您和系统未初始化它,则说为0)结果

结论-不能将
sendbytes
用于异步io操作。这里没有定义什么。当io完成时,您可以并且需要获得此值。你是如何得到它的取决于你是如何通知完成的

  • 如果你用-你就把它放进去了 在
    dwnumberOfByTestTransfered中
    论据
  • 如果你用-你就把它放进去了 在
    numberOfByTestTransferred
    参数中
  • 如果你使用自己的IOCP,并且-你有 指向调用
    WSASend
    (或 另一个io功能-这已经是您的任务确定 操作完成后,此
    lp重叠
    使用)。在
    这一点你可以要求这样做
    
    lpOverlapped
    bWait
    您可以设置为任何值-这并不重要,因为操作已经完成-api将返回 在任何情况下都会立即(无需等待),并且您得到了 在
    LPNumberOfByTestTransferred
    中传输的字节数。然而 只需复制
    lpOverlapped->InternalHigh
    将值传递到
    *LPNumberOfByTest
    ,以便您可以, 自己使用
    InternalHigh
    而不调用
    GetOverlappedResult

:“如果
lpOverlapped
参数不是
NULL
,则对此参数(
lpnumberofybytest
)使用
NULL
,以避免潜在的错误结果。”如果使用异步io,则不得使用(忽略)
sendbytes
,但是
overlapped\u Send.InternalHigh
GetOverlappedResult
返回的NumberOfByTestTransferred(它实际上只需将
InternalHigh
值复制到此处)在执行操作时completed@IgorTandetnik文件是错误的。在使用SP2的Windows XP上,这将因访问冲突而崩溃,因为没有检查lpNumberOfBytesSent是否为
NULL
WSASend
在Windows XP上的工作方式不同。它不会忽略
lpNumberOfBytesSent
,即使它被设置为
NULL
,并且函数被称为重叠函数。
*lpNumberOfBytesSent = (ULONG)lpOverlapped->InternalHigh;