(六)、确认机制通知到上层应用?
  这是一个比较美好的愿望,上层应用在调用内核层接口发送大段数据,内核完成发送并且收到对方完整确认,然后通知上层应用已经发送成功,那么在一些环境下,可以节省不少业务层面交互步骤。
  (七)、NAT网关超时
  IPV4有限,局域网环境借助于NAT路由设备扩展了接入终端设备的数量。当建立一个TCP长连接时,NAT设备需要维护一个内部终端连接外部服务器所使用的内部IP:PORT与出去的IP:PORT映射对应关系。这个关系需要维护,比较耗费内存资源,有超时定时器清理,否则会导致内存撑爆。
  不同NAT设备超时值不一样,因此才需要心跳辅助,确保经过NAT设备的连接一直保持,避免因过长的时间被踢掉。比如针对中国移动网络连接持久时间一般设置为不超过5分钟。各种网络略有差异,引入智能心跳机制比较合适。
  (八)、终端IP漫游
  手机终端经常在2G/3G/4G和WIFI之间切换,导致IP地址频繁发生改变。这样造成的后果是已有的网络请求-响应被放弃和终止,需要人工干预或重新发起请求,存在资源浪费现象。
  支持Multipath TCP的终端设备,可以同时利用 2G/3G/4G 和 WiFi 建立Mutlpath连接,通过多点优化网络下载,且互为备份。可以很好解决多个网络共存的情况下,一个网络中断不会导致全局请求处理中断,在设备的连接稳定和可靠性方面有所增强。
  当然,服务器之间也可以利用Multipath TCP的多个网络增强网络吞吐量。
  现状是:
  目前只有IOS 7以及后续版本支持
  Linux kernel 3.10实验分支上可以看到其支持身影,但何时合并到主分支上,暂时未知
  进阶阅读:A closer look at the scientific literature on Multipath TCP
  (九)、TCP缓存膨胀
  当路由器接收到的数据包超越其队列长度时,一般会随机丢包,以减少膨胀。针对上层应用程序而言,延迟增加,或误认为数据丢失,或连接丢失等。
  遇到这种情况,一般建议快速发包,以避免丢失的数据部分。内核层面今早升级到新版,不低于3.6即可。
  进阶阅读:Bufferbloat
  (十)、TCP不是可靠的
  IP和TCP协议在头部都会有check sum错误校验和机制,16位表示,反码相加,结果求反,具体可参考 TCP校验和的原理和实现。一般错误很轻松可检测出来,但遇到两个16位数字相加后结果不变的情况一筹莫展了
  以太网帧CRC32校验一般情况下都很OK,但可能遇到两端隔离多个路由器情况下,有可能出现问题,比如陈硕老师提供的一张图:

  上图中Client向Server发了一个TCP segment,这个segment先被封装成一个IP packet,再被封装成ethernet frame,发送到路由器(图中消息a)。Router收到ethernet frame (b),转发到另一个网段(c),后Server收到d,通知应用程序。Ethernet CRC能保证a和b相同,c和d相同;TCP header check sum的强度不足以保证收发payload的内容一样。另外,如果把Router换成NAT,那么NAT自己会构造c(替换掉源地址),这时候a和d的payload不能用tcp header checksum校验。
  路由器可能偶然出现硬件/内存故障导致收发IP报文出现多bit/单bit的反转或双字节交换,这个反转如果发生在payload区,那么无法用链路层、网络层、传输层的check sum查出来,只能通过应用层的check sum来检测。因此建议应用层要设法添加校验数据功能。
  大文件下载添加校验保证数据完整性,一般采用MD5,也用于防止安全篡改
  参考资料:
  Paper《When the CRC and TCP checksum disagree》
  The Limitations of the Ethernet CRC and TCP/IP checksums for error detection
  Amazon S3遇到的单bit反转线上事故
  (十一)、小结
  在这个满世界都是TCP的环境下,要想对TCP动大手术,这个是不太可能的,因为它已经固化到已有的系统内核和固件中。比如升级终端(比如Android/IOS等)系统/固件,Linux服务器内核,中间设备/中介设备(如路由器等),这是一个浩大工程,目前看也不现实。
  TCP位于系统内核层,内核空间的升级、修复,为麻烦。服务器端升级还好说一些,用户终端系统的升级那叫一个难。用户空间/用户核的应用升级、改造相对比来说可控性强,基于此Google专家们直接在UDP协议上进行构建、并且运行在用户空间的QUIC协议,综合了UDP的轻量和TCP的可靠性,是一个比较新颖的方向。
  若是对以后底层传输协议有所期望的话:
  在用户空间(用户核)出现可以定制的协议,类似于QUIC
  传统的TCP/UDP可以运行在用户空间,直接略过内核
  完整协议栈以静态链接库形式提供给上层应用
  上层应用可以在编译、打包的时包含其所依赖协议栈静态链接库so文件
  dpdk/netmap等Packet IO框架 + 用户空间协议堆栈,数据将从网卡直接送达上层应用
  Linux内核重要性降低,常规的SSH系统维护
  虽然TCP存在这样、那样的问题,但目前还是无法绕过的网络基础设施,但稍微明白一些不足的地方,或许会对我们当前使用的现状有所帮助。