网络工程师(8)——TCP为什么可靠

我们知道IP只是“尽力”,并不保证可靠性,所以传输可靠性必须由TCP来完成。

怎么保证可靠呢?TCP提供了乱序重排、应答确认、报文重传和流量控制四种机制。

乱序重排、应答确认都跟序号有关。由于网络或“多线程”等因素,接收方收到的数据段很可能是乱序的,不过,因为每个TCP封装都有序号,接收方重组起来非常容易。

发送方每发送一个数据段,如果都等着收到接收方的确认后再发下一个,这效率太低了。我们在解释Acknowledgement Number确认号时,曾举过一个栗子,发送方的数据有1000字节,接收方收到后的确认号填写1001,是告诉发送方前面的都收到了,下次从序号1001开始发。

那么,如果发送方发送了多个数据段,共5000字节,接收方只需发一个确认号为5001的报文,是不是就可以呢?

没错,TCP就是这么干的!这就大大提高了效率。至于一次收多少字节再发确认,由接收方window决定。

就好像两人打电话,听对方说话时,你时不时“嗯”一声,表示你在听。不必对方每说一句话你就“嗯”,当然对方说了半天你不“嗯”也不行,对方会问“还在吗”,是不是这个理儿?

TCP的报文重传有两种独立的办法。

一种是超时重传,发送方收不到确认的时候用。我们都知道网速并不是稳定的,传输时的每个报文的延时也不一样。TCP会根据报文的往返时间(RTT)自动调整超时重传时间(RTO)。发送方每发一个报文段都会开始计时,如果时间超过RTO还没收到这个报文段的确认,就重传该报文段。

另一种方法是快速重传,发送的数据在路上丢失的时候用。

我们看下图:

接收方收到序号1后,回复确认号2,希望下次收到序号2的报文段,但却乱序收到比序号2大的3、4、5报文段,于是连续发出确认号为2的报文段。如果发送方连续三次收到重复的确认号,立即重发该报文段,而不管是否超时。

接下来,我们讨论下TCP中的window窗口。

刚才提到过,window可以提高确认效率,不必让接收方为每个报文段都发确认。另外,window还有一个很重要的作用,那就是流量控制。

首先要明白一点,应用程序不论发送还是接收数据,都会先把数据放入缓冲区,再从缓冲区中发出或读取数据。就像秘书,先把事情整理归纳好,再一次性向你汇报。

这个缓冲区大小,反映了应用程序一次能处理数据的能力。如果接收方应用程序处理速度比发送方的发送速度慢,就会造成接收方缓冲区“溢出”。实际上,发送方发送速度和接收方处理速度很难一致。

这就需要window来调整了。

TCP在三次握手建立连接时,会协商双方缓冲区window大小。如果因为接收方处理速度较慢,接收方会通过window告知发送方,实现动态调整,避免“溢出”。

发送方会根据接收方确认报文中的window值来调整每次发出多少报文,这叫“滑动窗口”。

图中的“发送方窗口大小”不仅会向左“滑动”,它的大小也会根据网络带宽、时延变化及接收方window而动态改变。关于这点,我们以后在QoS中讨论。

TCP把数据可靠地传输完成后,还有一个重要工作,拆除连接。就像我们打完电话需要挂断一样。

TCP拆除连接需要“四次挥手”。


小Q:注意看TCP封装中的window只占2个字节,最大仅表示64K字节的缓冲区。这在网络早期带宽非常低、电脑内存很小的时候没问题。但是现在这个值早就不够用了。怎么解决这个问题?感兴趣的小伙伴可以了解一下window乘积因子。

欢迎留言讨论。

你可能感兴趣的:(网络工程师(8)——TCP为什么可靠)