tcp报文什么时候会真正发送

当用户使用tcp socket发送数据时,数据会立即被发送吗?不一定,tcp报文真正的发送由内核来定。那么满足什么条件的时候,tcp报文才会真正被发送?

用户调用tcp socket的send函数,在内核调用tcp_sendmsg进入tcp协议栈,tcp协议栈的出口是tcp_transmit_skb,通过该函数将报文发送给ip层。

讨论tcp报文什么时候会真正发送,先看一下有哪些条件会导致tcp报文不会被发送,当这些条件都不满足的时候,那么tcp就会被真正发送。本文只列出一个典型的环节,tcp协议栈的具体实现要复杂的多。

autocroking

自动软木塞,在满足某些条件时,数据不会被立即发送,而是在缓冲区缓存。

/* If a not yet filled skb is pushed, do not send it if

* we have data packets in Qdisc or NIC queues :

* Because TX completion will happen shortly, it gives a chance

* to coalesce future sendmsg() payload into this skb, without

* need for a timer, and with no latency trade off.

* As packets containing data payload have a bigger truesize

* than pure acks (dataless) packets, the last checks prevent

* autocorking if we only have an ACK in Qdisc/NIC queues,

* or if TX completion was delayed after we processed ACK packet.

*/

static bool tcp_should_autocork(struct sock *sk, struct sk_buff *skb,

int size_goal)

{

return skb->len < size_goal &&

READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_autocorking) &&

!tcp_rtx_queue_empty(sk) &&

refcount_read(&sk->sk_wmem_alloc) > skb->truesize &&

tcp_skb_can_collapse_to(skb);

}

这个条件判断的比较谨慎,只有4个条件都满足时,才不会立即发送。

(1)数据的长度小于size goal,还没有达到目标,先不发送。size goal是基于mss和gso计算出来的,一般比mss要大。

(2)autocorking使能,我感觉这个条件应该作为第一个条件,这个功能的开关。

(3)sk->sk_wmem_alloc每向下层队列发送,则会增加;发送完成,则会减少。该条件满足,说明在底层队列中还有数据没有发送。

(4)当前这个skb还有一些空间没有使用,还可以追加一些数据,这个时候,可以不发送

tsq tasklet

被autocorkong限流的报文什么时候会真正发送?通过tsq tasklet发送,如下代码所示,当对socket进行限流时,会设置一个标记TSQ_THROTTLED。

if (tcp_should_autocork(sk, skb, size_goal)) {

/* avoid atomic op if TSQ_THROTTLED bit is already set */

if (!test_bit(TSQ_THROTTLED, &sk->sk_tsq_flags)) {

NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTOCORKING);

set_bit(TSQ_THROTTLED, &sk->sk_tsq_flags);

}

/* It is possible TX completion already happened

* before we set TSQ_THROTTLED.

*/

if (refcount_read(&sk->sk_wmem_alloc) > skb->truesize)

return;

}

当报文从底层队列中发走并释放skb时,会调用函数tcp_wfree,在该函数中会调度tsq_tasklet,最后发送socket中的数据。

tsq全称为tcp small queue,避免在底层队列中有太多的小包,在autocorking中做的事情和在函数tcp_small_queue_check中做的事情是相似的。

tasklet是小任务,linux中任务延后执行的机制有软中断、tasklet。延后执行的机制,在应用开发中也常用到,比如线程池,可以延后处理任务。

拥塞窗口和发送窗口

拥塞窗口主要看已经发送还没有确认的报文数量,如果这些报文的数量大于拥塞窗口,则不发送。

发送窗口看要发送的数据是不是超过了发送窗口的大小,如果是,则不发送。

发送窗口由接收侧控制,在tcp建立连接的过程中会根据初始条件确定发送窗口的大小,

拥塞窗口:慢启动,拥塞避免,拥塞处理

发送窗口:由接收窗口决定

nagle

收到ack的时候

重传

定时机制

用户控制

相关推荐
IT19952 分钟前
Nginx + HTTP 服务:解决响应数据包截断,返回内容不全问题
网络·网络协议·http
重生之高冷汉堡包6 分钟前
Perplexity爬虫怎么做?2026常见方案对比、实操教程与问题排查
大数据·网络·爬虫·安全·ai
Brilliantwxx10 分钟前
【Linux】IO(上)全篇:文件本质、C 接口、系统调用与文件描述符
linux·运维·服务器·c语言
承渊政道10 分钟前
Linux网络学习【深入理解应用层HTTP协议、Cookie与Session机制及HTTPS协议原理】
linux·网络·学习·http·cookie·session
北风toto11 分钟前
Linux 服务器通过 tgz 离线部署 Docker
linux·服务器·docker
重生之小比特14 分钟前
【Linux系统】13 基础IO(上)
linux·运维·服务器
启博网络20 分钟前
IPv4枯竭、NAT穿透卡顿?用公网IPv6直连搭建异地组网,速度直接起飞
网络·远程安全访问·启博
羑悻的小杀马特21 分钟前
超越Bridge:全面掌握Docker网络隔离与通信的底层逻辑!
运维·网络·docker·容器
开开心心就好1 小时前
安卓PDF处理工具,免费无广告零弹窗
android·服务器·开发语言·算法·pdf·ocr
电梯界知识分子1 小时前
江西赣州赣县三层设计师自建房:1700mm中空极限利用,全观光铝合金电梯的精度与防震处理
大数据·服务器·网络·人工智能·家用电梯