TCP如何实现/保证有序数据传输?

时间:2012-03-30 03:07:22

标签: sockets tcp inorder

我想知道TCP如何实现按顺序交付。

让我们说这是事件列表

  1. 发送了packet1,收到了ack。
  2. 发送了packet2,未收到确认。
  3. 发送了packet3。
  4. 发送了packet4。
  5. ack4收到了。
  6. ack3收到了。
  7. ack2收到了。
  8. 你能告诉我顺序发生了什么吗?

2 个答案:

答案 0 :(得分:8)

简短的回答是每个数据包都包含偏移信息(伪装成序列号),指定其有效载荷位于流中的位置。

假设发生以下情况:收到数据包1,未收到数据包2,接收数据包3和4。此时接收TCP堆栈知道在缓冲区中复制数据包3和4的内容的位置,并且它知道它仍然没有接收到先前的数据,因此它将使数据包1数据可供读取,但它不会使数据包3或4数据可用,直到收到数据包2.

传输TCP堆栈通常不会在发送下一个数据包之前等待任何单个数据包的确认,但是如果它没有收到给定数据包的确认(并且ACK可以并且在一个数据包中捆绑在一起以提高效率) ,它将重新发送它,直到收到ACK。

事件的确切顺序取决于网络条件,TCP堆栈实现,选择的TCP策略,套接字选项和其他因素。

答案 1 :(得分:4)

TCP数据包具有序列号(自启动以来,从内存开始的字节偏移),并且ACK消息确认已收到特定偏移量:

enter image description here

所以你最终会遇到这样的情况:

data 1 (10 bytes)          ->
                           <- ack (10, data1)
data 2 (15 bytes)          ->
data 3 (10 bytes)          ->
data 4 ( 8 bytes)          ->
                           <- ack (25, data1/2/3)
                           <- ack (33, data1/2/3/4)

换句话说,无论确认如何,发送方都可以继续发送,直到其缓冲区已满(必须保留未确认的数据包,以防需要重新发送它们)。

发送和确认之间的这种“断开连接”可以大大加快数据流的速度。

在接收端,数据包可能无序到达,并且它们会被保留,直到可以按顺序将某些内容传送到更高级别。

例如,如果data 3data 2之前到达,则接收端将保持到data 2到达,然后两者都会向上发送以进行投放。