应用层设置周期性的心跳Keepalive,这些keepalive在TCP的眼中,那就是application data,毫无疑问,一旦这些keepalive在超时时间内没有收到对方TCP的ACK,就会继续重传,至于重传的上限次数是多少,这要看具体的TCP协议的实现,一般至少重传8次,越往后重传的时间间隔将越来越大,这样可以避免网络重新收敛对TCP连接的短期影响。
上文最后这句话有点难以理解,它的意思是,当前使用的路径即使断了,路由协议会动态选择新的物理链路,那么后续的TCP重传报文会使用新的链路到达目的地,这样就避免了TCP超时断开的风险。
所以,并不是说只有TCP断开重连才会选择更优路径,移动网络IP层会实时更新最新的、最优路径,这是TCP报文所依赖的IP网络平台的特性,无论你喜欢或不喜欢,它一直就是这样的表现形式!
接下来多些一点内容有助于读者理解TCP长连接。
TCP长连接的存在可以优化客户端访问服务器的访问效率。如果没有TCP长连接,客户端每次访问服务器,都要三次握手,平添了1.5RTT时间延迟。
而TCP长连接如果存在,客户端可以节省建立TCP连接的时间 = 1.5RTT。
但凡事有利必有弊,TCP长连接的存在,如果没有数据的刷新,至少存在1个风险:移动网络使用了NAT技术。换句话说,TCP长连接在NAT设备上,是以一个NAT表项条目存在着,这个条目是有寿命的,如果没有数据的刷新,一般2-20分钟不等会被删除。
一旦删除,客户端与服务器的数据到达NAT设备时,会重新创建NAT条目吗?
不会!
NAT设备如何处理?
丢!
为了避免NAT条目超时删除,通过应用层心跳周期性保活,可以避免这种恶劣情况的发生。
但是周期性的心跳并不是万能的,比如以下情况的发生:
(1) 网络拥塞
重传的心跳报文被一次次无情丢弃
(2) NAT设备重启
NAT条目消失
(3) 服务器重启
TCP四元组消失
(4) 网络环路
心跳报文永远无法到达服务器
(5) 网络收敛缓慢
TCP报文一直被丢,一直到TCP被Reset也没有恢复
当TCP长连接即使配置了心跳,也没有逃脱被Reset的命运,可以从上文找原因。