TCP Socket SendAsync操作是否可以在不传输BufferList中的所有字节的情况下完成?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP Socket SendAsync操作是否可以在不传输BufferList中的所有字节的情况下完成?相关的知识,希望对你有一定的参考价值。
在Mono 3.12上,我使用Socket.SendAsync(SocketAsyncEventArgs)
和TCP Stream Socket
来实现基于请求的流媒体协议。我正在使用SocketAsyncEventArgs.BufferList
设置多个数据缓冲区。
在Socket
和SocketAsyncEventArgs
的文档中,我找不到任何关于在使用SocketAsyncEventArgs.Completed
时是否可以在没有发送所有字节的情况下引发BufferList
,留下我们必须对SocketAsyncEventArgs.BytesTransferred
进行验证的印象。
另一方面,Socket.BeginSend
做出了这种保证
当你的应用程序调用
BeginSend
时,系统将使用一个单独的线程来执行指定的回调方法,并将在EndSend
上阻塞,直到Socket
发送所请求的字节数或抛出异常。
当使用SendAsync
和SocketAsyncEventArgs.BufferList
时,规范对传输的字节数有什么保证?
假设事件是用SocketError.Success
完成的。
当使用带有SocketAsyncEventArgs.BufferList
的SendAsync时,规范对传输的字节数有什么保证?
首先,可以在错误时引发事件,在这种情况下,您可以假设并非所有字节都已传输。为此,您需要测试SocketError.Success的SocketAsyncEventArgs.SocketError。此外,如果您参考“规范”,我假设您的意思是(Microsoft)Windows套接字文档(因为您链接到此以获取SendAsync和其他说明)。
为了在成功的情况下调用Completed事件时,为了确定文档所说或暗示的传输字节数,我们必须做几个步骤。第一步是查看SendAsync是否使用重叠I / O.这个问题在Overlapped Input / Output文档中得到了解答。对于底层传输提供程序,此机制的实现是必需的,因此它是唯一可以保证可用于Windows套接字的重叠I / O机制。因此,SendAsync保证使用具有WSA_FLAG_OVERLAPPED属性的套接字。
请注意,检查SendAsync reference implementation表明SendAsync确实使用了带有重叠I / O的WSASend,但这只是一个观察。
第二步是确定重叠的I / O告诉我们关于已完成事件的信令与传输字节数量的关系。这种情况在几个地方有描述,例如在这个Overlapped I/I and Event Objects页面:'当发送缓冲区被消耗时将提供指示'。 [WSASend]函数的备注部分给出了更多详细信息:'当完成传输时,将调用例程的完成或事件对象的设置时,将发生完成指示' 。
这仍然留有一些空间来准确解释这句话。基本上它表示数据已被套接字范围内的底层传输机制接受和确认。这并不一定意味着它已到达远程端点协议层,这将取决于通信协议。对于TCP流式套接字,我推断它表明数据已到达远程端点。
这里的结论是文档保证(对于非错误情况)SendAsync completed事件仅在所有字节都已传输时引发。
你想在这里查看什么?您是否担心在发送所有字节时没有收到所有字节的原因?
当您一次发送100个字节并尝试在另一端读取100个字节时,无法保证您将一次性接收所有字节。它可以分成100个1字节的数据包。这就是TCP的工作原理。您总是需要累积字节,然后形成并分离您的数据包。这就是所谓的TCP套接字管道工作。 WCF和所有这些包装器都是为你做的。
以上是关于TCP Socket SendAsync操作是否可以在不传输BufferList中的所有字节的情况下完成?的主要内容,如果未能解决你的问题,请参考以下文章
linux C语言 socket如何判断socket_fd对应的socket是否断开?(是否连通是否正常连接)recv()tcp_info TCP_ESTABLISHEDkeepalive