在Mono 3.12上,我将 Socket.SendAsync(SocketAsyncEventArgs) 与TCP流Socket结合使用以实现基于请求的流协议(protocol)。我正在使用 SocketAsyncEventArgs.BufferList 设置多个数据缓冲区。

Socket SocketAsyncEventArgs 的文档中,我找不到关于在使用SocketAsyncEventArgs.Completed时不发送所有字节的情况下是否可以提高 BufferList 的记载,这给我们留下了必须针对 SocketAsyncEventArgs.BytesTransferred 进行验证的印象。

另一方面, Socket.BeginSend 可以保证



使用SendAsyncSocketAsyncEventArgs.BufferList时,规范对传输的字节数有何保证?

假设该事件已使用 SocketError.Success 完成。

最佳答案

将SendAsync与SocketAsyncEventArgs.BufferList一起使用时,规范对传输的字节数有何保证?

首先,可以在发生错误时引发事件,在这种情况下,您可以假定并非所有字节都已传输。为此,您需要测试SocketAsyncEventArgs.SocketError的SocketError.Success。另外,如果您指的是“规范”,则我假设您的意思是(Microsoft)Windows套接字文档(因为您已链接至此以获得SendAsync和其他说明)。

为了在成功的情况下成功调用Completed事件时,也能弄清文档中所说的或暗示的传输字节数,我们必须采取一些步骤。第一步是查看SendAsync是否使用重叠的I/O。该问题在Overlapped Input / Output文档中得到了回答。此机制的实现对于基础传输提供程序是强制性的,因此,它是保证可用于Windows套接字的唯一重叠的I/O机制。这样,可以确保SendAsync使用具有WSA_FLAG_OVERLAPPED属性的套接字。

请注意,对SendAsync reference implementation的检查表明,SendAsync确实在使用WSASend和重叠的I/O,但这仅是一个观察。

第二步是确定哪些重叠的I/O告诉我们有关已完成事件的信令与传输字节数的关系。这种情况在多个地方都有描述,例如在此Overlapped I/I and Event Objects页面上:“当发送缓冲区被消耗时将提供指示”。 [WSASend]函数的备注部分提供了更多详细信息:“当缓冲区已被传输器占用时,将出现完成指示,调用例程的完成或事件对象的设置” 。

这仍然为该短语的确切解释留出了空间。基本上,它说数据已被套接字范围外的基础传输机制接受并确认。这并不一定意味着它已经到达远程端点协议(protocol)层,这将取决于通信协议(protocol)。对于TCP流套接字,我可以推断出它指示数据已到达远程端点。

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

关于c# - 是否可以在不传输BufferList中所有字节的情况下完成TCP套接字SendAsync操作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41470548/

10-13 09:05