TCP Socket SendAsync操作是否可以在不传输BufferList中的所有字节的情况下完成?

Sot*_*lis 20 c# sockets mono

在Mono 3.12上,我正在使用Socket.SendAsync(SocketAsyncEventArgs)TCP Stream Socket来实现基于请求的流式传输协议.我正在使用SocketAsyncEventArgs.BufferList设置多个数据缓冲区.

在对文件SocketSocketAsyncEventArgs,我无法找到的是否提及任何SocketAsyncEventArgs.Completed可以在不被时发送的所有字节被提出BufferList时,留下我们必须验证对印象SocketAsyncEventArgs.BytesTransferred.

另一方面,Socket.BeginSend做出保证

当您的应用程序调用时BeginSend,系统将使用单独的线程来执行指定的回调方法,并将阻塞,EndSend 直到Socket发送所请求的字节数或引发异常.

规范对使用SendAsynca 时传输的字节数有什么保证SocketAsyncEventArgs.BufferList

假设事件已完成SocketError.Success.

Ton*_*oij 2

当使用带有 a 的 SendAsync 时,规范对传输的字节数有何保证SocketAsyncEventArgs.BufferList

\n\n

首先,该事件可能会因错误而引发,在这种情况下,您可以假设并非所有字节都已传输。为此,您需要测试 SocketAsyncEventArgs.SocketError 是否为 SocketError.Success。另外,如果您引用“规范”,我假设您指的是(Microsoft)Windows Sockets 文档(因为您链接到此文档以获取 SendAsync 和其他描述)。

\n\n

为了弄清楚文档对于成功调用 Completed 事件时传输的字节数的说明或暗示,我们必须执行几个步骤。第一步是查看 SendAsync 是否使用重叠 I/O。这个问题在重叠输入/输出文档中得到了解答。对于底层传输提供程序来说,此机制的实现是强制性的,因此它是保证可用于 Windows 套接字的唯一重叠 I/O 机制。因此,SendAsync 保证使用具有 WSA_FLAG_OVERLAPPED 属性的套接字。

\n\n

请注意,对SendAsync 参考实现的检查表明 SendAsync 确实使用具有重叠 I/O 的 WSASend,但 \xe2\x80\x99 只是一个观察结果。

\n\n

第二步是确定重叠 I/O 告诉我们有关已完成事件的与传输字节数相关的信号的信息。这种情况在多个地方都有描述,例如在此重叠 I/I 和事件对象页面:\xe2\x80\x98 当发送缓冲区已被消耗时\xe2\x80\x99 将提供指示。[WSASend] 函数的备注部分给出了更多详细信息: \xe2\x80\x98 当缓冲区被消耗时,将出现完成指示,调用例程的完成或事件对象的设置通过传输\xe2\x80\x99。

\n\n

这对于这句话的准确解释还是有一定的空间的。基本上它表示数据已被套接字范围之外的底层传输机制接受并确认。这并不一定意味着它已经到达远程端点协议层,这取决于通信协议。对于 TCP 流式套接字,我会推断它表明数据已到达远程端点。

\n\n

这里的结论是,文档保证(对于非错误情况)仅在所有字节都已传输时才引发 SendAsync 完成事件。

\n