TCP的可靠传输

前言

面试官:你知道TCP吗?

李三:知道的,TCP是面向连接的可靠的……

面试官:那你说说TCP它是怎么保证可靠的?

李三:what???我三次握手四次挥手贼溜,要不你问问这个?

面试官:没关系的,那今天就到这吧!

天天说TCP是可靠的可靠的,我们怎么能连它是怎么保证可靠的都不知道了。这个时候你就应该告诉面试官:所谓可靠传输,即要保证接收方从缓存区收到的字节流和发送方发出的字节流是一致的。一是需要建立连接来保证(这个我贼溜,要不你问问我这个?)。二是要有能检测到出数据是否出错并在出错时解决错误,还得保证报文段整合成应用层报文是有序的。在TCP中使用首部的序列和字段实现报文段检错,使用序号、窗口号、确认号来保证有序,并使用重传机制解决问题。

检测报文段数据是否出错

TCP检验和:计算时会临时增加一个伪首部(包括源IP、目标IP、UDP长度等)计算后删除,检验数据是否出错

伪首部, 又称为伪包头(Pseudo Header):是指在 TCP 的分段或 UDP 的数据报格式中,在数据报首部前面增加源 IP 地址、目的 IP 地址、IP 分组的协议字段、TCP 或 UDP 数据报的总长度等共12字节,所构成的扩展首部结构。此伪首部是一个临时的结构,它既不向上也不向下传递,仅仅只是为了保证可以校验套接字的正确性。

TCP的可靠传输

计算方法 ​ 发送方 ​ 1.检验和置0 ​ 2.把伪首部、首部和数据部分拆分为16位的字串 ​ 3.按二进制反码计算出这些16位字的和 ​ 4.将和求反填入校验和字段 ​ 接收方 ​ 1.按发送方2、3步计算出结果 ​ 2.无差错时结果为1,否则出错

确认重传机制

确认重传机制是保证接收方收到了数据,且保证接收方可能没收到数据时重传数据。需要学习的主要有两种方法:停止等待协议和以字节为单位的滑动窗口方法

停止等待协议

停止等待协议是一种简单的协议,因为它过于简单,信道利用率低性能差,并没有被使用。每发送完一个分组就停止发送,等待,收到确认后再发送下一个分组。

停止等待协议可以将数据传输分成三种情况:

  1. 无差错情况:依次发送

  2. 出现差错: 如何实现:每发送一个分组设置一个超时计时器,收到确认撤销计时器,计时器时间超过重发

    超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些(具体多少后面再讨论)

    保证能重传的前提:1.必须暂时保留已发送的分组的副本 2.分组和确认分组都必须进行编号

  3. 确认丢失和确认迟到 引起的原因:网络拥堵 采取的行动:丢弃发送方重传的重复分组,向发送方发送确认

以字节为单位的滑动窗口机制

为了解决停止等待协议一次只发一个分组导致信道利用率低的问题,同时保证发送多少数据有据可循,引入以字节为单位的滑动窗口机制。

在TCP连接建立时,会根据发送窗口的大小在TCP首部中设置窗口值,接收方根据窗口值设置接收窗口的大小,窗口大小会由流量控制和拥塞控制来动态调整。发送窗口分为四个部分,接收窗口分为三个部分,如下:

TCP的可靠传输

发送窗口会按顺序依次发送,直到允许但尚未发送的窗口大小为0,当收到确认后窗口向前滑动。接收窗口依次接收数据,当最小序号要收到的数据还没收到就不能返回确认收到,其他未按序收到的先缓存下来等前面的按序收到了再返回确认并将数据交付给主机,保证了有序

发生差错和确认迟到、丢失时,同停止等待协议。

累积确认

TCP要求接收方必须有累计确认功能,以减少传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息捎带上。TCP标准规定,确认推迟的时间不应超过0.5秒。捎带确认实际不经常发生,因为大多数应用程序很少同时在两个方向上发送数据

超时重传时间的选择

使用自适应重传算法,根据多个往返时间RTT计算动态得到。

选择确认SACK

解决的问题:只传送缺少的数据而不重传已经正确到达接收方的数据 RFC2018规定,如果要使用选择确认SACK,那么在建立TCP连接时,就要在TCP首部的选项中加上”允许SACK“的选项 选择确认SACK的前提是有累积确认