【问题标题】:Who take care tcp message order谁负责tcp消息顺序
【发布时间】:2020-07-10 01:31:18
【问题描述】:

我用recvrecvfrom 监听linux 中的tcp 套接字。

谁负责让我按正确的顺序获取 tcp 数据包?

内核是否会小心,所以如果数据包 1 在数据包 2 之后出现,内核将同时丢弃/保存数据包 2 直到数据包 1 到来?

或者我可能需要按照 tcp 数据包的顺序处理用户空间?

【问题讨论】:

  • 使用 TCP 时,您将按照发送的顺序接收数据。
  • 用户空间甚至看不到与 TCP 的数据包边界。它纯粹是一个数据流。

标签: c linux sockets tcp


【解决方案1】:

引用维基百科,

在协议栈的较低级别,由于网络拥塞、流量负载平衡或不可预测的网络行为,IP 数据包可能会丢失、重复或无序传送。 TCP 检测到这些问题,请求重新传输丢失的数据,重新排列乱序数据,[...]

您将以正确的顺序(或根本不)接收数据是协议的固有属性。

请注意,TCP 是一种流协议,因此您甚至无法检测数据包边界。对recv/recvfrom 的调用可能会返回数据包的一部分,并且可能会返回来自多个数据包的字节。

【讨论】:

    【解决方案2】:

    在任何正常情况下,在基于 Linux 的系统上,这是由内核处理的。

    您可以找到source code here,这是一个精简版:

    /*  Queue data for delivery to the user.
     *  Packets in sequence go to the receive queue.
     *  Out of sequence packets to the out_of_order_queue.
     */
    if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
       /* packet is in order */
    }
    
    if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
       /* already received */
    } 
    
    if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp)))
        goto out_of_window;
    
    if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
        /* Partial packet, seq < rcv_next < end_seq */
    }
    
    /* append to out-of-order queue */
    tcp_data_queue_ofo(sk, skb);
    

    以及使用 RB 树进行重新排序的 actual implementation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-04
      • 1970-01-01
      • 2017-01-04
      • 1970-01-01
      • 1970-01-01
      • 2015-05-07
      相关资源
      最近更新 更多