libjingle源码解析(5)-【PseudoTcp】建立UDP之上的TCP(3):对成块数据流的处理
PseudoTcp对成块数据流的处理
上一篇谈论了TCP和PTCP对交互数据流的处理方法。这一篇谈论另一个数据流--成块数据流。成块数据流主要采用滑动窗口协议和慢启动算法来控制成块数据的流量。
滑动窗口滑动窗口允许发送方在停止并等待确认前可以连续发送多个分组。因此发送方不必每发一个就停下来等待,这样可以加速数据的传输。这个Nagle算法冲突么?不会,因为成块数据流的分组都是满载传输的,根据Nagle算法,当等待发送数据的大小和窗口大小都大于MSS时,会立即发送。
如果发送方一直传输数据会出现经常丢包的现象,特别是快的发送方发给慢的接收方。当接收方还没有处理数据,发送方就接连发来了数据会填满接收方的缓冲区,从而后续的数据将被丢弃,为了减少网络上丢包的次数,用一种机制来限制发送方传输数据。
因此出现了滑动窗口,如下图:
滑动窗口分为4个部分:
上图1~3为发送并确认的数据段
上图4~6为已经发送,但是没有被确认的数据段
上图7~9为可用的窗口,即滑动窗口,发送方还可以发送的数据段空间
上图10以上为不能够发送。
当接收方确认数据后,滑动窗口两边不断的向右移动。
窗口合拢:当发送方发送数据并等待确认时,滑动窗口的左边向右移动。
窗口张开:当接收方收到数据并确认且释放缓冲区数据时,右边向右移动。
窗口收缩:当接收方的缓冲区大小变小时,右边向左移动,但不建议使用这种方式。
滑动窗口时通过窗口大小来更新。当接收方收到数据后,重新计算接收缓冲区的大小,并通告发送方。如果通告窗口大小为0,则发送方不能再发送数据,等到窗口大小为非0,这样可以有效的避免因接收方缓冲区满导致的分组的丢失。
那么PTCP是怎么实现的呢?
PTCP通过m_rbuf_len来标示接收缓冲区大小。如果缓冲区大小小于65536时,m_rwnd_scale为0,m_rcv_wnd标示窗口大小,而大于65535时,通过如下算法来调整m_rbuf_len和m_rwnd_scale。调整后根据缓冲区中可用空间来更新窗口大小m_rcv_wnd 。为什么选择65535为界限呢?因为在PTCP的头部中window字段的长度为16个bit,只能支持窗口打小范围0~65535(包含65535)。