Loading...

TCP的核心参数-MTU、MSS、RTT、RTO、cwnd、ssthresh

MTU和MSS,管【单个TCP包到底发多大最合适】,是整个传输的基础;

RTT和RTO,管【包发出去之后,怎么保证对方一定收到,丢包了怎么办】,是TCP可靠传输的核心;

cwnd和ssthresh,管【一次能连续发多少个包,怎么既跑满带宽,又不把网络堵死】,是TCP拥塞控制的核心。

MTU & MSS

MTU(最大传输单元,Maximum Transmission Unit)

平时用的以太网、WiFi,硬件层面就规定了一个完整的IP数据包,最大不能超过1500字节,这个上限就是MTU。
如果IP包超过MTU,就会被拆成好几个小分片传输,只要有一个分片丢了,整个包就得全量重传,特别影响效率,还可能被防火墙拦截。

MSS(最大报文段长度,Maximum Segment Size)

这是基于MTU算出来的、TCP包里真正能装的业务数据的最大长度——要把IP头、TCP头的空间提前扣掉。
以太网默认MTU1500字节,标准IP头和TCP头各占20字节,所以默认MSS就是1460字节。

它是TCP三次握手的时候,客户端和服务端协商出来的,最终取两边的最小值,目的就是从源头避免IP拆包。

RTT & RTO

RTT(往返时延,Round-Trip Time)

我发一个TCP包出去,到我收到对方回的【我收到了】的ACK确认包,这一来一回花的时间,就是RTT。
它是网络环境决定的客观值,网络越拥堵、跨的路由越多,RTT就越长,会实时波动,是算RTO的唯一基础。

RTO(重传超时时间,Retransmission TimeOut)

我发出去一个包,会设一个定时器,要是超过这个时间还没收到ACK,我就认为这个包丢了,马上重发一个,这个定时器的时间就是RTO。
RTO完全是基于RTT算出来的,不是固定死的。

它必须比RTT大一点。

如果太小了,ACK还在路上就瞎重传,浪费带宽;

但太大了,真丢包了半天不重传,传输变慢。

所以,网络波动RTT变了,RTO也会跟着实时调整。

cwnd & ssthresh

这两个参数是TCP拥塞控制的核心,TCP刚建连的时候,根本不知道当前网络能扛住多大流量,发少了浪费带宽,发多了直接把网络堵死,所以用这两个参数控制发送节奏。

cwnd(拥塞窗口,Congestion Window)

TCP发送端自己维护的【油门】,单位是MSS。这个参数决定了在没收到对方ACK之前,我最多能连续发多少个包。

比如cwnd=10,就是最多连续发10个MSS大小的包,不用等ACK。
需注意的是,cwnd不是固定的,网络越好、丢包越少,cwnd就越大,发送速度就越快;一旦丢包,就会马上降下来。

ssthresh(慢启动阈值,Slow Start Threshold)

cwnd的【换挡开关】,用来划分两个发送阶段,单位也是MSS。
当cwnd < ssthresh时,进入慢启动阶段,cwnd每过一个RTT就直接翻倍,指数级快速涨速,尽快把带宽跑满;

当cwnd ≥ ssthresh时,进入拥塞避免阶段,cwnd每过一个RTT才加1,线性慢慢涨,避免冲太猛把网络堵死。
一旦检测到网络拥堵丢包,ssthresh会立刻降到当前cwnd的一半,再根据丢包的严重程度调整cwnd,重新控制发送节奏。

Code Road Record