一、介绍
在TCP重传的时候,并没有限制TCP只能重传与初传完全相同的报文段大小,TCP允许执行重组包(repacketization),发送一个更大的TCP报文段,进而增加性能。TCP在重传时候允许重组包同时提供了一种判别虚假重传的方法。在linux中参数/proc/sys/net/ipv4/tcp_retrans_collapse为非0值的时候打开重传重组包功能,为0的时候关闭重传重组包功能。
二、wireshark示例
我们来看两个wireshark示例,这次我们在ubuntu16.04的默认配置下进行测试,除了修改自增的内核参数tcp_discard_on_port=9877以便进行测试外,其他参数保持默认设置。默认设置下的tcp_retrans_collapse为1
1、TLP后RTO,然后重组包
client与server端建立连接后,client发送一次数据,server正常回复ACK
接着server发送两个数据包No6和No7,当前缓存中没有待发数据了,设置TLP定时器为(2*RTT)
在TLP定时器超时的时候,重传No7数据包(即No8数据包),进行loss probe探测,同时设置RTO定时器
接着RTO定时器超时,进行指数回退过程,即No9-No12,在这个指数回退过程中,server应用层写入8bytes的数据,但是由于拥塞控制,这个数据暂时只能放在server端缓存中而没能发出去,从这里我们可以看到linux重传重组包的过程中并不会把之前未发送的数据一起组包发送
接着client回复No13确认包,server端收到这个ACK确认包后重传结束,并把刚刚积压在缓存中的数据发出去(No14)
client端回复ACK确认包,整个传输过程结束。
2、SACK重传下的重组包
在重传重组包的过程中,遇到已经被SACK确认的数据包就会结束重组包过程
如下图所示No12数据包通过ack number确认了No6数据包,通过SACK信息确认了No9数据包,在随后的RTO超时过程中,No7和No8两个数据包一起重传,No10数据包单独重传。
补充信息:
1、linux下重传重组包代码点tcp_retrans_try_collapse