基于“流”通信
TCP协议是传输层协议,实现的是端口到端口(port)的通信。更进一步,TCP协议虚拟了文本流(byte stream)的通信。在TCP协议与”流”通信中讨论的TCP传输需要一个前提:TCP连接已经建立。
计算机数据的本质是有序的0/1序列 (如果以byte为单位,就叫做文本流)。计算机的功能就是储存和处理文本流。CPU + 存储器 + 存储设备实现了文本流在同一台计算机内部的加工处理。通过一些IO,比如屏幕和键盘,文本流实现了人机交互。而进一步,如果网络通信可在不同计算机之间进行文本流的交互,那么我们就和整个计算机系统的数据处理方式实现了对接。
IP协议和UDP协议采用的是数据包的方式传送,后发出的数据包可能早到,我们并不能保证数据到达的次序。
TCP协议确保了数据到达的顺序与文本流顺序相符。当计算机从TCP协议的接口读取数据时,这些数据已经是排列好顺序的“流”了。比如我们有一个大文件要从本地主机发送到远程主机,如果是按照“流”接收到的话,我们可以一边接收,一边将文本流存入文件系统。这样,等到“流”接收完了,硬盘写入操作也已经完成。如果采取UDP的传输方式,我们需要等到所有的数据到达后,进行排序,才能组装成大的文件。
片段与编号
TCP片段的头部(header)会存有该片段的序列号(sequence number)。这样,接收的计算机就可以知道接收到的片段在原文本流中的顺序了,也可以知道自己下一步需要接收哪个片段以形成流。比如已经接收到了片段1,片段2,片段3,那么接收主机就开始期待片段4。如果接收到不符合顺序的数据包(比如片段5),接收方的TCP模块可以拒绝接收,从而保证呈现给接收主机的信息是符合次序的“流”。
TCP可靠性
TCP的可靠性是这么体现的:在每收到一个正确的、符合次序的片段之后,就向发送方(也就是连接的另一段)发送一个特殊的TCP片段,用来知会(ACK,acknowledge)发送方:我已经收到那个片段了。这个特殊的TCP片段叫做ACK回复。如果一个片段序号为L,对应ACK回复有回复号L+1,也就是接收方期待接收的下一个发送片段的序号。如果发送方在一定时间等待之后,还是没有收到ACK回复,那么它推断之前发送的片段一定发生了异常。发送方会重复发送(retransmit)那个出现异常的片段,等待ACK回复,如果还没有收到,那么再重复发送原片段… 直到收到该片段对应的ACK回复(回复号为L+1的ACK)。
当发送方收到ACK回复时,它看到里面的回复号为L+1,也就是发送方下一个应该发送的TCP片段序号。发送方推断出之前的片段已经被正确的接收,随后发出L+1号片段。ACK回复也有可能丢失。对于发送方来说,这和接收方拒绝发送ACK回复是一样的。发送方会重复发送,而接收方接收到已接收过的片段,推断出ACK回复丢失,会重新发送ACK回复。
TCP 的连接是可靠的,还体现在 重传机制和滑动窗口机制
TCP 滑动窗口机制:
滑窗
上面的工作方式中,发送方保持发送->等待ACK->发送->等待ACK…的单线工作方式,这样的工作方式叫做stop-and-wait。stop-and-wait虽然实现了TCP通信的可靠性,但同时牺牲了网络通信的效率。在等待ACK的时间段内,我们的网络都处于闲置(idle)状态。我们希望有一种方式,可以同时发送出多个片段。然而如果同时发出多个片段,那么由于IP包传送是无次序的,有可能会生成乱序片段
在stop-and-wait的工作方式下,乱序片段完全被拒绝(序列号对不上,会等待重发),这也很不效率。毕竟,乱序片段只是提前到达的片段。我们可以在缓存中先存放它,等到它之前的片段补充完毕,再将追加在后面。
然而,如果一个乱序片段实在是太过提前(太“乱”了),该片段将长时间占用缓存。我们需要一种折中的方法来解决该问题:利用缓存保留一些“不那么乱”的片段,期望能在段时间内补充上之前的片段(暂不处理,但发送相应的ACK);对于“乱”的比较厉害的片段,则将它们拒绝(不处理,也不发送对应的ACK)。
(1)窗口机制
TCP滑动窗口技术可以通过动态改变窗口大小来实现对端到端设备之间的数据传输进行流量控制。
滑窗(sliding window)被同时应用于接收方和发送方,以解决以上问题。发送方和接收方各有一个滑窗。当片段位于滑窗中时,表示TCP正在处理该片段。滑窗中可以有多个片段,也就是可以同时处理多个片段。滑窗越大,越大的滑窗同时处理的片段数目越多(当然,计算机也必须分配出更多的缓存供滑窗使用)。
(2)流量控制
主机和服务器之间可以通过滑动窗口来实现流量控制。
TCP协议会根据情况自动改变滑窗大小,以实现流量控制。流量控制(flow control)是指接收方将 window的大小通知给发送方,从而指导发送方修改发送 window的大小。接收方将该信息放在TCP头部的window size区域:
发送方在收到window size的通知时,会调整自己滑窗的大小。这样,发送窗口变小,文本流发送速率降低,从而减少了接收方的负担。
超时重传机制
超时重传机制是指:当发送方送出一个TCP片段后,将开始计时,等待该TCP片段的ACK回复。如果接收方正确接收到符合次序的片段,接收方会利用ACK片段回复发送方。发送方得到ACK回复后,继续移动窗口,发送接下来的TCP片段。如果直到计时完成,发送方还是没有收到ACK回复,那么发送方推断之前发送的TCP片段丢失,因此重新发送之前的TCP片段。这个计时等待的时间叫做重新发送超时时间(RTO, retransmission timeout)。
快速重传机制
快速发送机制如果被启动,将打断计时器的等待,直接重新发送TCP片段。
快速重传机制:实现了另外的一种丢包评定标准,即如果连续收到3次 ACK,发送方就认为这个seq的包丢失了,立刻进行重传,这样如果接收端回复及时的话,基本就是在重传定时器到期之前,提高了重传的效率。
TCP的可靠机制虽然保证了数据安全,但是往往也带来某些方面的缺陷:例如TCP慢启动和TCP全局同步现象。
慢启动:
TCP连接刚建立时,不是一下子就能把握TCP窗口值大小的,会从一个小的窗口值慢慢往上加,最后协商成功,达到稳定的windows大小。
TCP全局同步:
当网络发生堵塞时,报文就不能及时送达目的端。对于TCP报文,如果大量的报文被丢弃,将造成TCP超时,从而引发TCP慢启动,使得TCP减少报文的发送。当队列同时丢弃多个TCP连接的报文时,将造成多个TCP连接同时进入拥塞避免和慢启动状态以调整并降低流量,这就被称为TCP全局同步现象。这样多个TCP连接发往队列的报文将同时减少,而后又会在某个时间同时出现流量高峰,如此反复,使网络资源利用率低。
已使用 Microsoft OneNote 2013 创建。
