在现有复杂的网络环境中,如果我们的产品提供网络传输功能,特别是提供点对点的大数据量网络传输服务,我们会经常收到一小部分用户的抱怨,传输不稳定而且速度慢。针对这部分环境,在排除了应用实现的代码问题之后,通过抓包分析,我们可以发现, TCP 的拥塞控制实现策略对现有的低速网络,特别是上行受限的 ADSL 用户网络不具很好的适应性。我们把发送端标记为 A ,接收端标记为 B, 具体如下:
A B 建立连接后, A 端拥塞控制窗口 cwnd=mss, 应用层向 A TCP 发送缓冲区放入数据之后, A B 发送一个 mss 长度的 TCP 封装数据, B 端收到并发回 ACK A 端收到 ACK cwnd += mss(cwnd=2*mss) A 再次向 B 发送 2 mss TCP 封装数据。当 cwnd 增大到 n * mss 时, A B 发送 n mss 长度的 TCP 封装数据包, B A 确认,但是只确认了前 i i < n )个 , 即是 B 没有收到 i + 1 n 个包。则由 TCP 的实现策略,当 i >= 3 时,传输将进入超时重传或快速恢复。 i< 3, 则只有进入超时重传。不管是进入哪个流程,都会影响到传输的效率。如果 n <= 3, 则传输会频频进入超时重传流程,对于以 100 毫秒为基本单位的定时器实现的超时检查,每次该事件发生时,将至少浪费数百毫秒连接无利用,严重影响传输的速度。
针对这类问题,如果我们使用的是操作平台提供的 TCP 传输通道,我们只能通过侦测传输通道的网络状况,计算出每次发送包合适的大小,减少拥塞发生的概率。这种处理方式能够稍稍增强传输的稳定性,甚至可以提高传输速度,增强用户体验。
但是这种方式是通过控制发送数据包在一定大小实现的,对于传输定量的数据,显然是增加了 send 函数的系统调用,降低了程序的系能。同时也不是解决问题的根本之道,因为应用层获取 TCP 连接的拥塞控制窗口 cwnd 是不现实的,通过应用层的逻辑计算很难保证准确,从架构角度讲不应该是应用层所关心的事情。
重写 tcp 的实现对于一般的产品而言,是不现实的,但是不应该是阻止我们研究该问题的理由。通过前面的分析,我们知道在现实的网络环境中,有些环境下两端点之间的物理设备由于带宽以及处理能力的限制,每次发送超过 2 个或 3 mss 大小的数据包就高概率丢包,由此进入频繁的超时重传。如果可靠传输控制流程能够加入侦测机制,当发现发送超过 m mss 大小的数据包时,在运行环境内就会丢包,如此设定拥塞控制窗口的一个关系值 m ,当达到 m 后,进入一个比拥塞控制流程更慢的增长过程,则系统能够大大提高传输速度。
 今天先写到这里,改天再续!