谁负责tcp消息顺序

谁负责tcp消息顺序,c,linux,sockets,tcp,C,Linux,Sockets,Tcp,我在linux中使用recv或recvfrom收听tcp套接字 谁负责让我按正确的顺序获得tcp数据包 内核会注意吗?如果包1在包2之后出现,内核会同时退出/保存包2直到包1出现 或者我需要按照tcp数据包的顺序处理用户空间?引用维基百科的话 在协议栈的较低级别,由于网络拥塞、流量负载平衡或不可预测的网络行为,IP数据包可能丢失、复制或无序传送TCP检测这些问题,请求重新传输丢失的数据,重新排列无序数据,[…] 协议的固有属性是您将以正确的顺序接收数据(或者根本不接收) 请注意,TCP是一种流协

我在linux中使用
recv
recvfrom
收听tcp套接字

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

内核会注意吗?如果包1在包2之后出现,内核会同时退出/保存包2直到包1出现

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

引用维基百科的话

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

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


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

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

你可以找到,这里有一个简略的版本:

/*  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);
/*用于向用户传递的队列数据。
*数据包按顺序进入接收队列。
*将无序数据包发送到无序队列。
*/
如果(TCP_SKB_CB(SKB)->seq==tp->rcv_nxt){
/*包装整齐*/
}
如果(!在(TCP\U SKB\U CB(SKB)->结束顺序,tp->rcv\U nxt)之后){
/*已收到*/
} 
如果(!在(TCP\U SKB\U CB(SKB)->顺序,tp->rcv\U nxt+TCP\U接收窗口(tp))之前)
跳出窗外;
如果(在(TCP\U SKB\U CB(SKB)->顺序,tp->rcv\U nxt)之前){
/*部分数据包,seq

除了使用RB树进行重新排序之外:

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