通过上图可以看到,这次大块数据交互不像“交互式输入”那样小分组发送,而是每次发送都会充满整个报文段允许的最大值(MSS)从而达到更加的效率,当然这已经是另一次场景了,而这个场景才是我们平常使用到的场景,例如你看个新闻,刷个微博等。从图中也可以看得到窗口的真实作用,服务端一开始就告诉客户端它的窗口大小为4096,客户端要发送的数据远远大于4096(例如一张图片可以就不止了),客户端可以连续以最大报文段的容量连续发送,直到服务端的窗口(缓冲区)被沾满时,才会停止发送,等待服务端的窗口大小变更通知,再继续发送。其实这里的成块数据传送隐藏了许多的规则细节,例如发送的数据不够MSS怎么办,需要等么?又或者服务端的窗口可以腾出了1个字节的空间也要告诉客户端的话就会引发“糊涂窗口综合症”的问题。这些细节后续会慢慢介绍,这里更多先总结窗口的基本作用。
窗口(缓冲区)的总大小是固定的,只不过因为窗口的“空闲”是随着接收方的确认而变动,从而让窗口看起来是动态变化的,这个动态(左右收缩)其实是站在双方的视觉看窗口的空闲状态而言,双方都会计算和维护当前窗口的大小, 例如发送方会计算它到底还有多少数据可以发送,而接收方会计算它到底还有多少窗口空间可以接收数据:
1)、称窗口左边沿向右边沿靠近为窗口靠拢,这种现象发生在数据被发送和确实时;
2)、当窗口右边沿向右移动时将允许发送更多的数据,我们称之为窗口张开。这种现象发生在另一端的接收进程读取已经确认的数据并释放了TCP的接收缓存时;
3)、当右边沿向左移动时,我们称之为窗口收缩。RPC强烈建议不要使用这种方式。
如果左边沿到达右边沿,则称其为一个零窗口,此时发送方不能够发送任何数据。就像“TCP窗口样例”显示的那样。不同系统默认的窗口大小不一样,例如有些是2048字节,有些是4096、8192或更大。但重要是“插口API允许进程设置发送和接收缓存的大小,接收缓存的大小是该连接上所能通告的最大窗口大小,有一些应用程序通过修改插口缓存大小来增加性能”。
2、慢启动
“接收窗口”并非万能,虽然可以通过增加缓存大小提高性能,但影响性能的远不止“接收窗口”的大小,还有网速、路由器等。迄今为止,发送方一开始便向网络发送多个报文段,直至达到接收方通告窗口大小为止。当发送方和接收方处于同一个局域网时这种方式是可以的,但是如果在发送方和接收方之间存在多个路由器时,就有可能出现一些问题。一些中间路由器必须缓存分组,并有可能耗尽存储器的空间。
现在TCP需要支持一种被称为“慢启动(slow start)”的算法。该算法通过观察到新分组进入网络的速率应该与另一端返回确认的速率相同而进行工作。慢启动为发送方的TCP增加了另一个窗口叫“拥塞窗口(congestion window)”,记为cwnd。拥塞窗口是发送方使用的流量控制,而通告窗口则是接收方使用的流量控制。