在Mono 3.12上,我将 Socket.SendAsync(SocketAsyncEventArgs)
与TCP流Socket
结合使用以实现基于请求的流协议(protocol)。我正在使用 SocketAsyncEventArgs.BufferList
设置多个数据缓冲区。
在 Socket
和 SocketAsyncEventArgs
的文档中,我找不到关于在使用SocketAsyncEventArgs.Completed
时不发送所有字节的情况下是否可以提高 BufferList
的记载,这给我们留下了必须针对 SocketAsyncEventArgs.BytesTransferred
进行验证的印象。
另一方面, Socket.BeginSend
可以保证
使用SendAsync
和SocketAsyncEventArgs.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/