最近在带一个项目的过程中,看到测试同学提了一BUG:对软件进行网络限速之后,软件会自动掉线,并且根据日志能够看出是服务器端主动关闭了该连接,导致客户端掉线。而该BUG迟迟没有得到解决,于是叫上负责开发的同学,问其如何实现的keepalive的超时判断机制,负责同学的回答和我预料的完全一样:当在阀值N秒收不到对端发来的KEEPALIVE包,则认为网络出现问题,主动关闭该socket。

先不谈该处理的对错,我们首先分析一下keepalive的作用:

一、由于IP地址的短缺等原因,很多团体采用NAT的方式接入到互联网,NAT负责维护外部数据包到内网地址的映射关系(session),并且回收session算法中,主要是根据双端没有数据流动的时长。所以我们实现keealive一个主要的目的是防止NAT回收了session,导致我们的逻辑链接失效。

二、用户侦测连接的健康状况,如果一端每n秒发送一个数据包,而对应端n+m(m为一阀值,根据现有互联网状况而定)秒没有收到任何数据包,则可以认为该连接出现问题,需要重建连接。

对于NAT,其回收session并不是根据有无keepalive包,而是有无数据(IP包)流动。而网络健康的判断规则也应该是有无数据包流动。我们应用中采用keepalive的机制是为了在应用无正常业务数据包时,为 上述 一 二而做。

所以,简单期间,直接修改超时判断标准,当收到对端发来的任何数据包时,都应该更新最后一次收包时间。