TCP的send()函数保证按顺序到达吗?

4
已知send()函数的返回值可能小于发送内容的长度,这意味着只有部分消息而非整个消息已经被传输。我需要发送两个内容分别为"ABC"和"DEF"的数据包,它们的长度都是3。我想在调用send()传输"ABC"后再发送"DEF"。然而,情况可能是send()对于"ABC"的返回值小于其长度3。我认为存在消息未按顺序传递的可能性。例如,如果"ABC"的返回值是2,则接收到的消息将是"ABDEF"。
TCP中的send()函数是否保证按顺序到达?

如果套接字处于非阻塞模式,则send()的返回值只能小于提供的长度。在阻塞模式下,它会一直阻塞,直到所有字节都被传输到套接字发送缓冲区,因此您描述的问题不可能发生。 - user207421
1个回答

4
首先,send() 函数本身并不保证什么,它只是将你要发送的数据写入套接字缓冲区。操作系统会将数据分段(放置在 TCP 分段中),从而管理传输的可靠性。如果底层缓冲区已满,则返回值可能低于所需写入的字节数。这通常表明操作系统不能快速清空缓冲区,即您写入数据到缓冲区的速率高于数据被发送到网络(或被对方读取)的速率。
其次,TCP 是一种流协议,如果你 send() "ABC" 然后 "DEF",则没有关于数据如何分段的保证,它可能在一个数据包中结束,也可能分成六个数据包。就像将数据写入文件一样。
第三,网络堆栈(操作系统中的 TCP/IP 实现)保证按顺序交付,以及 TCP 所承诺的其他好处 - 可靠性、拥塞控制、流量控制等。

我理解这是缓冲区大小的问题,并且有许多事情需要保证顺序。谢谢您的回答。 - Mackerel
  1. 在阻塞模式下,send() 函数总是发送整个缓冲区。这是由 Posix 保证的。
  2. 在非阻塞模式下,如果 send() 函数没有发送整个缓冲区,几乎可以肯定地说接收方读取速度比发送方慢,而不仅仅是你所提供的原因,顺序相反。
- user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接