首选我们需要明确两个TCP概念，一个是rtt，一个是rto. 首先RTT是什么，RTT简单来说，就是我发送一个数据包，然后对端回一个ack，那么当我接到ack之后，就能计算出从我发送出包到接到过了多久，这个时间就是RTT。RTT的计算是很简单的，就是一个时间差。 TCP重传机制Timeout的设置对于重传非常重要。 设长了，重发就慢，丢了老半天才重发，没有效率，性能差 设短了，会导致可能并没有丢就重发。于是重发的就快，会增加网络拥塞，导致更多的超时，更多的超时导致更多的重发。 而RTO呢，RTO也就是tcp在发送一个数据包之后，会启动一个重传定时器，而RTO就是这个定时器的重传时间。 在通俗的讲就是，我一开始预先算个定时器时间，如果你回复了ack那正好，如果没有回复给我ack，然后RTO定时器的时间又到了，那么我就重传。 那么这个时候，就有问题了，由于RTO是指的这次发送当前数据包所预估超时时间,那么RTO就需要一个很好的算法来统计，来更好的预测这次的超时时间。 RTO不是固定写死的配置，而是经过RTT计算出来的。 ``` tcp_frto - INTEGER Enables Forward RTO-Recovery (F-RTO) defined in RFC5682. F-RTO is an enhanced recovery algorithm for TCP retransmission timeouts. It is particularly beneficial in networks where the RTT fluctuates (e.g., wireless). F-RTO is sender-side only modification. It does not require any support from the peer. By default it's enabled with a non-zero value. 0 disables F-RTO. This file can have one of the following values: 0 Disabled. 1 The basic version F-RTO algorithm is enabled. 2 Enable SACK-enhanced F-RTO if flow uses SACK. The basic version can be used also when SACK is in use though in that case scenario(s) exists where F-RTO interacts badly with the packet counting of the SACK-enabled TCP flow. ``` 其实大家大可不必深究学习RTO的计算的算法，多数情况RTT都是比较小的，当RTT 小于 RTO MIN时，linux下RTO初始值可以理解为RTO的那个最小200ms值（最小200ms,最大120s）。 当然如果超过RTO最小值，那这个时间就要斟酌了，最坏单次不会超过RTO MAX 。 那么什么时候会引起超时重传 ? 我给你发seq data数据，你应该给我回复ack确认数据已经接受. 1. 发送SYN成功对端接收失败，去程丢包。 2. 接收ack失败，返程丢包。 3. ack握手失败。 总的来说，作为发送端我只要是没有收到ack，我就会重发， 我们这里主要是讨论什么时候重试发包，另外需要发几次，每次的间隔时间。 下面是内核关于RTO定时器的最长时间，最短时间限制。 ``` #xiaorui.cc #define TCP_RTO_MAX ((unsigned)(120*HZ)) // 120秒 #define TCP_RTO_MIN ((unsigned)(HZ/5)) //0.2s #define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC2988bis initial RTO value */ #define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now * used as a fallback RTO for the * initial data transmission if no * valid RTT sample has been acquired, * most likely due to retrans in 3WHS. */ ``` # 相关 - https://unix.stackexchange.com/questions/210367/changing-the-tcp-rto-value-in-linux - https://whitequark.org/blog/2011/09/12/tweaking-linux-tcp-stack-for-lossy-wireless-networks/ - https://www.networkworld.com/article/2227856/opensource-subnet/best-networking-tweaks-for-linux.html - https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt