vlambda博客
学习文章列表

依靠三次握手就能保证TCP协议可靠传输?

几乎每一个程序员都知道TCP的三次握手,每个面试几乎都问你一遍的经典问题。但是大部分对于网络接触不深的同学,容易误以为依靠三次握手就能保证TCP的可靠传输。


在经典著作《计算机网络》谢希仁书中指道“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”这也是TCP为啥采用三次握手能避免的一个问题。三次握手只是TCP数据报在建立连接时确保可靠传输的一部分。


在整个数据报发送和传输过程中,TCP的可靠传输还由众多的机制和算法进行控制着,我们不妨惊叹家用几十块钱的路由器居然那么N逼,还会算法。


TCP首先采用三次握手来建立连接、四次挥手来释放连接。其次TCP采用了连续ARQ协议,即自动重传请求(Automatic Repeat-reQuest)来保证数据传输的正确性,使用滑动窗口协议来保证接收方能够及时处理接收到的数据,进行流量控制。最后TCP使用慢开始、拥塞避免、快重传、快恢复来进行拥塞控制,避免网络拥堵。下面我们将分别介绍三次握手、检验和、连续ARQ、拥塞控制和四次挥手来确保TCP的可靠传输。

01

建立连接:三次握手


依靠三次握手就能保证TCP协议可靠传输?

客户端通过三次握手的方式和服务器建立连接,建立完连接之后,我们就可以愉快的进行数据传输了。


在正常的情况下我们的数据流被分割MTU为1500的数据包进行封装头部和尾部传输最大传输单。(Maximum Transmission Unit,MTU)

因为数据流要进行分割,就需要对分割数据包的校验,收到确认,以及我们的传输流量进行控制。

02

数据校验:


这张图是我们的TCP数据包结构,可以看到是有我们tcp报文的首部和数据部分组成,其中我们校验和就是采用CRC冗余校验的算法对数据部分和头部进行校验,TCP校验和是一个端到端的校验和,由发送端计算,然后由接收端验证。其目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。如果接收方检测到校验和有差错,则TCP段会被直接丢弃。

依靠三次握手就能保证TCP协议可靠传输?

03

ARQ确认机制:


在传输过程中由于网络性能,会造成数据的丢和延迟到达,如果我们的发送端没有在确定的时间内收到接受端的返回的数据,这个时候我们的发送端就会对刚才的数据报进行重发,这也就有了我们tcp传输的停止等待确认协议。

以下两种情况均为传输过程中数据包传输出现问题,触发我们的重传机制:


确认丢失:

依靠三次握手就能保证TCP协议可靠传输?

当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:


丢弃这个重复的M1消息,不向上层交付。

向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。


确认迟到:

依靠三次握手就能保证TCP协议可靠传输?

A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:

· A收到重复的确认后,直接丢弃。

· B收到重复的M1后,也直接丢弃重复的M1。


在这种确认重传的机制下,我们会发现,实现十分简单,但是也有严重的缺陷。

从从发送端发送数据到收到确认的响应过程中,中间浪费了大把时间。


依靠三次握手就能保证TCP协议可靠传输?

04

滑动窗口:


由于停止等待ARQ协议信道利用率太低,所以需要使用连续ARQ协议来进行改善。这个协议会连续发送一组数据包,然后再等待这些数据包的ACK。


连续ARQ协议通常是结合滑动窗口协议来使用的,发送方需要维持一个发送窗口

依靠三次握手就能保证TCP协议可靠传输?

图(a)是发送方维持的发送窗口,它的意义是:位于发送窗口内的5个分组都可以连续发送出去,而不需要等待对方的确认,这样就提高了信道利用率。


连续ARQ协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。例如上面的图(b),当发送方收到第一个分组的确认,就把发送窗口向前移动一个分组的位置。如果原来已经发送了前5个分组,则现在可以发送窗口内的第6个分组。


接收方一般都是采用累积确认的方式。也就是说接收方不必对收到的分组逐个发送确认。而是在收到几个分组后,对按序到达的最后一个分组发送确认。如果收到了这个分组确认信息,则表示到这个分组为止的所有分组都已经正确接收到了。


累积确认的优点是容易实现,即使确认丢失也不必重传。但缺点是,不能正确的向发送方反映出接收方已经正确收到的所以分组的信息。比如发送方发送了前5个分组,而中间的第3个分组丢失了,这时候接收方只能对前2个发出确认。而不知道后面3个分组的下落,因此只能把后面的3个分组都重传一次,这种机制叫Go-back-N(回退N),表示需要再退回来重传已发送过的N个分组。


滑动窗口协议在在发送方和接收方之间各自维持一个滑动窗口,发送发是发送窗口,接收方是接收窗口,而且这个窗口是随着时间变化可以向前滑动的。它允许发送方发送多个分组而不需等待确认。TCP的滑动窗口是以字节为单位的。


05

拥塞控制:


引用滑动窗口的机制不旦能提高确认重传的网络利用率,还可以实现TCP网络拥塞控制。


虽然有了滑动窗口机制,如果一开始就发送大量数据,很有可能引发很多问题。

TCP加入慢启动机制,先发少量的数据探探路,看看当前网络的拥塞状态,再决定按照多大的速率进行传送,刚开始时,定义拥塞窗口的大小为1,每次接收到一个ACK应答,拥塞窗口值加1,每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口。这样的拥塞窗口增长的速度是指数级别的,慢启动只是指初始时慢,但是增长速度很快,不久就可以造成网络拥塞。为了不让窗口一直加倍增长,我们引入一个慢启动的阈值,当拥塞窗口超过这个阈值的时候,不在按指数方式增长,而是按照线性方式增长。


06

四次挥手断开连接:


最后又回到我们经典的四次挥手断开TCP的网络连接。

为什要进行四次挥手断开连接,这个得记住,面试会考:

tcp是全双工通信,服务端和客服端都能发送和接收数据。

tcp在断开连接时,需要服务端和客服端都确定对方将不再发送数据。