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的时候

重传

定时机制

用户控制

相关推荐
圆圆讲门店34 分钟前
挑选同城获客服务机构时需要考量的核心因素都有哪些?
大数据·网络·人工智能·python
筝筝ba1 小时前
openBMC功耗封顶GUI测试
服务器
制造业的搬运工1 小时前
扫地机器人主板 PCB 选型:深圳线路板与普通板的 8 项工艺指标对比与参数清单
网络·科技·制造·科普·pcb工艺
niuTaylor2 小时前
飞腾 FT-2000/4 Ubuntu 内存卡 / NVMe SSD 系统制作完整指南
linux·服务器·人工智能·驱动开发·单片机
Huangjin007_3 小时前
【Linux 系统篇(二十五)】文件(二) 系统文件I/O详解
linux·运维·服务器
XiaoMaqqqq3 小时前
目前知名的IP驱动产业新场景新工具有哪些
网络·python·网络协议·tcp/ip
李永奉4 小时前
中科蓝讯SDK开发-BT897X、BT891X、AB573X、AB572X 系列 触摸按键提示音功能实现
网络·单片机·嵌入式硬件·mcu·物联网
ShineWinsu4 小时前
对于ProtoBuffer:ProtoBuffer的介绍以及安装
linux·网络·google·协议·序列化·反序列化·protobuffer
云表无代码开发4 小时前
日本开发者彻底破防:中文太强了!换成英文直接裂开
大数据·服务器·人工智能·microsoft·信息可视化
Eddyp4 小时前
避开溢价!艾默生 TREX2 手操器省钱选型攻略
网络·其他·百度·微信·微信公众平台·新浪微博