2

因特网有两个核心协议:IP和TCP。IP,Internet Protocol(因特网协议),负责联网主机之间的路由选择和寻址;TCP,即Transmission Control Protocol(传输控制协议),负责在不可靠的传输信道上提供可靠的抽象层。TCP向应用层隐藏了大多数网络通信的复杂细节,比如丢包重发、按序发送、拥塞控制及避免、数据完整等等。采用TCP数据流可以确保发送的所有字节能够完整地被接收到,而且到达客户端的顺序也一样。

三次握手

所有TCP连接一开始都要经过三次握手,在客户端与服务端交换应用数据之前,必须就起始分组序序号,以及其他一些连接相关的细节达成一致,序列号由两端随机生成。

图片描述

  • SYN

    客户端选择一个随机序列号x,并发送一个SYN分组,其中还会包含其他TCP标志和选项。
    
  • SYN ACK

    服务器给x加1,并选择自己的一个随机序列号y,追加自己的标志和选项,然后返回响应。
    
  • ACK

    客户端给x和y加1并发送握手期间的最后一个ACK分组。
    

客户端可以在发送ACK分组之后立即发送应用数据,而服务器则必须等接收到ACK分组之后才能发送数据。这个启动通信的过程适用于所有的TCP连接,对于那些发送数据量比较少的应用来说,三次握手带来的延迟将对性能造成很大的影响。因此,提高TCP应用性能的关键,在于想办法重用连接。

拥塞预防及控制

  • 流量控制

流量控制是一种预防发送端过多向接收端发送数据的机制。否则,接收端可能因为忙碌、负载过重或缓冲区塞满而无法处理。为了实现流量控制,TCP连接的每一方都要通告自己的接收窗口(rwnd),其中包含能够保存数据的缓冲区空间大小信息。

图片描述

第一次建立连接时,两端都会使用自身系统的默认设置来发送rwnd。浏览网页通常是从服务器下载数据,因此客户端窗口更可能成为瓶颈。如果是在上传图片或视频,即客户端向服务器发送大量数据时,服务器的接收窗口又可能成为制约因素。

如果一端跟不上数据传输,那它可以向发送端通告一个较小的窗口。当窗口为0,则意味着必须由应用层先清空缓冲区,才能接收新的数据。这个过程贯穿于每个TCP连接的整个生命周期:每个ACK分组都会携带相应的最新rwnd值,以便两端动态调整数据流速,使之适应发送端和接收端的容量及处理能力。

  • 慢启动

流量控制可以防止发送端向接收端过多发送数据,但却没有机制预防任何一端向潜在网络过多发送数据。换句话说,发送端和接收端在连接建立之初,谁也不知道可用带宽是多少,因此需要一个估算机制,然后还要根据网络中不断变化的条件而动态改变速度。

慢启动的核心思想是,服务器通过TCP连接初始化一个新的拥塞窗口(cwnd,发送端对从客户端接收确认ACK之前可以发送数据量的限制)变量,将其设置为一个系统设定的保守值(linux中为initcwnd)。发送端不会通告cwnd变量,即发送端和接收端不会交换这个值。客户端与服务器之间最大可以传输(未经ACK确认的)数据量取rwnd和cwnd变量中的最小值。那服务器和客户端怎么确定拥塞窗口大小的最优值呢?解决方案就是慢启动,即在分组被确认后增大窗口大小,慢慢地启动。

新TCP连接传输的最大数据量取rwnd和cwnd中的最小值,而服务器实际上可以向客户端发送4个TCP段,然后就必须停下来等待确认。此后,每收到一个ACK,慢启动算法就会告诉服务器可以将它的cwnd窗口增加一个TCP段。每次收到ACK后,都可以多发送两个新的分组。TCP连接的这个阶段通常被为“指数增长”阶段,因为客户端和服务器都在向两者之间网络路径的有效带宽迅速靠拢。

很多应用层协议都运行在TCP之上,无论带宽多大,每个TCP连接都必须经过慢启动阶段。因此,我们不可能一上来就完全利用连接的最大带宽,对于一些短暂、突发的连接而言,常常会出现还没有达到最大窗口请求就被终止的情况。换句话说,很多Web应用的性能经常受到服务器与客户端之间往返时间的制约。因为慢启动限制了可用的吞吐量,而这对于小文件传输非常不利。

  • 拥塞预防

慢启动以保守的窗口初始化连接,随后的每次往返都会成倍提高传输的数据量,直到超过接收端的流量控制窗口,即系统配置的拥塞阈值窗口,或者有分组丢失为止,此时拥塞预防算法介入。

拥塞预防算法把丢包作为网络拥塞的标志,即路径中某个连接或路由器已经拥堵了,以至于必须采取删包措施。因此,必须调整窗口大小,否则将会造成更多的保丢失。

重置拥塞窗口后,拥塞预防机制按照自己的算法来增大窗口以尽量避免丢包。某个时刻,可能又会有包丢失,于是这个过程再从头开始。如果你看到过TCP连接的吞吐量跟踪曲线,发现该曲线呈锯齿状,那就是拥塞控制和预防算法在调整拥塞窗口,进而消除网络中的丢包问题。

队首阻塞

TCP在不可靠的信道上实现了可靠的网络传输。基本的分组错误检测与纠正、按序交付、丢包重发,以及保证网络最高效率的流量控制、拥塞控制和预防机制,让TCP成为大多数网络应用中最常见的传输协议。

虽然TCP很流行,但是实现TCP的种种机制会导致额外的延迟,对性能造成负面影响,特别是按序交付和可靠交付。想想看,每个TCP分组都会带着一个唯一的序号被发出,而所有分组必须按顺序传送到接收端。如果中途有一个分组没能到达接收端,那么后续分组必须保存在接收端的TCP缓冲区上,等待丢失分组重发并到达接收端。应用程序对TCP重发和缓冲区中排队的分组一无所知,必须等待分组全部到达才能访问数据。在此之前,应用程序只能在通过套接字读数据时感觉到延迟交付。这就是TCP的队首阻塞。

总结

  • TCP三次握手增加了整整一次往返时间
  • TCP慢启动被应用到每个新连接
  • TCP流量及拥塞控制会影响所有连接的吞吐量
  • TCP的吞吐量由当前拥塞窗口大小控制

大多数情况下,TCP的瓶颈都是延迟,而非带宽。


Jason
859 声望29 粉丝

« 上一篇
深入理解WebRTC
下一篇 »
谈谈HTTP缓存