TCP协议详解

2021-10-13 10:17:59 浏览数 (1)

概述

TCP(Transmission Control Protocol)传输控制协议

和UDP结构类似,由TCP首部和TCP数据报数据组成:

特点:

  1. TCP是面向连接的协议
  2. TCP的一个连接有两端(点对点通信,类似打电话?)
  3. TCP提供可靠的传输服务
  4. TCP提供全双工的通信
  5. TCP是面向字节流的协议(对应用层数据报合并或分拆)

TCP协议头部,固定20个字节,UDP头部只有8个字节,IP协议头部20个字节:

序号:

  1. 0~ 2^32-1
  2. 一个字节一个序号
  3. 数据首字节序号(第一个字节)

确认号:

  1. 0~ 2^32-1
  2. 一个字节一个序号
  3. 期待收到数据的首字节序号
  4. 确认号为N:表示N-1序号的数据都已经收到

比如,收到了序号为501的数据报,长度是100,下一次确认号则为601

数据偏移:

  1. 占4位:0~15,单位为:32位字(由此可以看出最大偏移为15*4,即TCP首部长度介于20-60个字节之间)
  2. 数据偏离首部的距离
  3. 不知道TCP选项有多长,所以用数据偏移表示真实的数据离头部偏移有多少

TCP标记:

  • 占6位,每位各有不同意义

URG、ACK、PSH、RST、SYN、FIN:

窗口:

  • 占16位:0~2^16-1
  • 指明允许对方发送的数据量(比如确认号501,窗口是1000,那么501-1500都是可以接收的)

紧急指针:

  • 紧急数据(URG=1)
  • 指定紧急数据在报文的位置

TCP选项:

  • 最多40字节(60-20)
  • 支持未来的拓展

可靠传输的基本原理

停止等待协议:

  • 发送方等待接收方的确认消息,才发送新的信息
  • 最简单的可靠传输协议
  • 通过超时重传保证可靠传输
  • 对信道的利用效率不高

停止等待协议,无差错的情况:

出差错的情况,超时重传,包括接收方没有收到发送方的消息:

超时重传,发送方没有收到接收方的确认信息:

超时重传,确认消息很久才收到:

小结:

  • 发送的消息在路上丢失了
  • 确认的消息在路上丢失了
  • 确认的消息很久才到

停止等待协议通过超时重传保证可靠传输

超时定时器:

  • 每发送一个消息,都需要设置一个定时器

连续ARQ协议:

  • ARQ(Automatic Repeat reQuest)自动重传请求
  • 批量发送和确认
  • 滑动窗口和累计确认是其两个重要概念

滑动窗口,收到前面的确认消息,滑动窗口向前移动,把滑动窗口内的未发送消息发送出去:

并不需要对每一个报文都确认,而采用累计确认的方法。如收到了5的确认消息,则认为1-5的消息都已经收到了,就把滑动窗口往前移动5格:

TCP协议的可靠传输

1. TCP的可靠传输基于连续ARQ协议

2. TCP滑动窗口以字节为单位

滑动窗口里面的7个字节都是可以发送的,左边是已经确认的字节序号,右边是不允许发送的字节序号,窗口内最左边是对方期待收到的下一个字节

窗口内又可分为已发送未确认和可用窗口,由于没收到前面的确认所以不能往前移动:

有可能窗口内都是已发送未确认,可用窗口=0。

没有按序收到确认消息,即收到后面的确认消息,但是没收到前面的,超时后,会从前面开始重传,效率低:

选择重传:

  • 选择性的重传某些消息,而不是重传所有消息
  • 选择重传需要指定需要重传的字节
  • 每一个字节都有唯一的32位序号

TCP选项最多40个字节(60-20),即最多10个序号,指定的是需要重传的边界,而不是字节,表明需要重传的一段范围

一段一段,如果里面存了1000和1500,指的是需要重传1000~1500这一段数据

TCP协议的流量控制

1. 特有的功能(UDP和其他协议没有)

2. 流量控制指让发送方发送速率不要太快

3. 流量控制是使用滑动窗口来实现的(确认号是501的话,如果窗口是1000,表明接收方希望接收501-1501的数据)

通过窗口大小控制对方发送速率:

如果丢失了最后的确认窗口变大(不为0)的消息,就会导致死锁,发送方一直等到对方窗口变大,接收方一直等待对方发送消息

坚持定时器(解决死锁):

  • 当发送方接收到窗口为0的消息,则启动坚持定时器
  • 坚持定时器每隔一段时间发送一个窗口探测报文

这种死锁相当于情侣一方A一直等待对方B改变脾气,而B已经改变了,但联系不到A,坚持定时器是A每隔一段时间问一下B,你改变了没有

TCP协议的拥塞控制

1. 一条数据链路经过非常多的设备

2. 数据链路中各个部分都有可能成为网络传输的瓶颈(导致拥塞)

与流量控制的区别:

  • 流量控制考虑点对点的通信量的控制
  • 拥塞控制考虑整个网络,是全局性的考虑
  • 报文超时则认为是拥塞(虽然不一定)

慢启动算法:

  • 由小到大逐渐发送数据量
  • 每收到一个报文确认,就加一(指数增长,1 2 4 8 16…)
  • 增长到慢启动阈值(ssthresh)后就不增长了

拥塞避免算法:

  • 维护一个拥塞窗口的变量
  • 只要网络不拥塞,就试探着把拥塞窗口调大(比如到了慢启动阈值16后,以后发送17、18、19…个报文)

二者结合,先进行慢启动算法,再进行拥塞避免算法:

上述过程就像一个人贪婪的过程

TCP连接的三次握手

涉及到3个TCP标记,SYN(连接请求)、ACK(代表已确认)、FIN(代表释放连接)

1.发送方发送:SYN=1, seq=x

2.接收方发送:SYN=1, ACK=1, seq=y, ack=x 1(小写的ack表示期望收到序列号的值是x 1,seq=y表示自己携带的序号为y)

3.发送方发送:ACK=1, seq=x 1, ack=y 1

  • 第一次和第二次握手都有SYN标记位,代表连接请求的意思
  • 第二次和第三次都有ACK的标记,对连接双方的序列号进行同步(都知道对方的序列号)
  • 发送方在第二次握手后就建立连接了,接收方在第三次握手后才建立连接,双方都建立连接后就可以进行数据传输了
  • 发送方发送第一次报文后进行同步已发送(SYNC-SENT)状态;
  • 接收方收到之前处于监听(Listen)状态,收到第一次报文后进入同步已接收(SYNC-RCVD)状态;
  • 发送方收到第二次报文后进行连接(ESTABLISHED)状态;
  • 接收方收到第三次报文后进入连接(ESTABLISHED)状态。
  • 即发送方状态为:同步已发送、建立连接。接收方状态为:监听、同步已接收、建立连接
  • 最早,接收方和发送方都是closed状态,即关闭。

为什么发送方要发出第三个确认报文(为什么需要第三次握手)?

  • 防止已经失效的连接请求报文传送到对方,引起错误

详细解释:

  • 发送方第一次握手时发送很久没有收到对方应答,于是发送了第二封,第二封比第一封更早到达,第一次便是失效的请求报文
  • 如果两次握手就能建立起连接:同一个请求发送两次(第一次超时)就会建立起两个连接,引起错误
  • 本来这是一个早已失效的报文段,但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。

虚线是假设两次握手就建立连接

TCP连接的四次挥手

比三次握手多出来的是第二次挥手,意思是我收到了,但是我现在还没传完,等会关闭

  • 主动关闭的一方状态变化为:建立状态、第一次等待(FIN-WAIT-1)、第二次等待(FIN-WAIT-2)、等待计时(TIME-WAIT)、关闭
  • 被动关闭的一方状态变化为:建立状态、关闭等待(CLOSE-WAIT)、最后确认(LAST-ACK)、关闭状态。
  • 主动关闭的一方最后有等待计时状态

MSL(MAX Segment Lifetime):最长报文段寿命

  • MSL建议设置为2分钟

等待计时器

  • 最长等待时间2MSL
  • 等待过程中,不会释放端口,只有等到等待计时器结束后,才释放
udp

0 人点赞