TCP协议+三次握手/四次挥手过程(带图详解!!!)

TCP连接建立——三次握手/四次挥手

1、什么是TCP?

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的通信协议,工作在传输层
应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接。
TCP运输连接主要有三个阶段:

  • 建立TCP连接,也就是三次握手
  • 数据传输,基于已经建立的TCP连接进行可靠的数据传输
  • 释放TCP连接,在完成数据的输送后,通过四次挥手来释放连接
    在这里插入图片描述

2、TCP首部格式

2.1 TCP首部格式是什么?

1、TCP 首部格式是 TCP 协议中用来传输数据的报文格式,用于在发送端和接收端之间传递 TCP 数据。TCP 首部包含了一些必要的信息,如源端口、目标端口、序列号、确认号、标志位等,用于控制和管理 TCP 连接。
2、在三次握手的过程中,双方会交换 TCP 首部信息,以建立连接。 TCP 连接建立后,双方可以通过 TCP 首部中的序列号(seq)和确认号(ack)来控制和管理数据传输。每个 TCP 报文都包含了 TCP 首部和数据部分,其中 TCP 首部用于控制和管理数据传输,数据部分用于传输实际的数据。(图片来源于网络搜索)
在这里插入图片描述

2.2 重要位置解释

  • 源端口/目的端口: 均占16比特,分别表示写入源端口号和目的端口号,用来标识发送/接收该TCP报文段的应用进程。
  • 序号(sequence number): 是发送数据包中的第一个字节的序列号,占32比特,取值范围是[0,2^32-1]。TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。首部中的序号字段值则是指的是本报文段所发送的数据的第一个字节的序号。

假设有两台主机 A 和 B 建立了 TCP 连接,A 向 B 发送了一个数据包,数据部分的长度为 100 字节,此时 A 会为这个数据包分配一个唯一的序列号,假设为 1000。B 收到这个数据包后,会发送一个确认包给 A,确认收到了这个数据包,并告诉 A下一个期望接收的序列号是 1100。这样,A 就知道 B 已经成功地接收了这个数据包,并且可以继续发送后续的数据。
如果某个数据包丢失了,TCP 协议会重新发送这个数据包,并在 TCP首部中使用之前分配的序列号,以告诉接收端这是之前发送的数据包。如果某个数据包重复传输了,TCP 协议会使用序列号来检查数据是否已经接收过。

序列号能有效保证TCP数据传输的可靠性和正确性,避免数据的重复传输和丢失。

  • 确认号(acknowledgement number): Ack序号,占32比特,取值范围[0,2^32-1],用于标识期望收到对方下一个TCP报文段的数据的第一个字节的序号,同时也是对之前收到的所有数据的确认。若确认号=n,则表明到序号n-1为止的所有数据都已正确接收,期望接收序号为n的数据。
    在 TCP 连接中,接收端会在每个 TCP 报文中包含确认号,以告诉发送端下一个期望接收的字节的序列号。发送端会根据确认号来确认接收端已经正确地接收到了数据,并继续发送后续的数据。

TCP 序列号用于标识数据流中的位置,TCP 确认号用于告诉发送端下一个期望接收的字节的序列号。两者结合起来,可以保证数据传输的可靠性和正确性。

  • 标志位ACK: ACK取值为1时确认号字段才有效;取值为0时确认号字段无效。TCP规定,在连接建立后所有传送的TCP报文段都必须把ACK置1。

不要将确认序号Ack与标志位中的ACK搞混了,ACK和确认号Ack的区别:
确认标志位 ACK 和确认号都是用于保证数据传输可靠性的机制,但具有不同的作用。确认标志位 ACK 的作用是告知发送方数据是否已经成功接收,确认号的作用是告知发送方接收方期望接收的下一个字节的序列号。Ack=seq+1

  • 同步标志位SYN: 在TCP连接建立时用来同步序号

假设有两台主机 A 和 B 建立 TCP 连接,A 需要发送一个带有 SYN 标志位的 TCP 报文给 B,请求建立连接。
A 发送的 SYN 报文中包含一个随机的序列号,B 收到这个 SYN 报文后,会回复一个带有 SYN 和 ACK 标志位的 TCP 报文,表示确认收到请求,并请求建立连接。B 回复的 SYN 和 ACK 报文中包含确认号,确认号被设置为 A 的序列号加 1,这就起到了SYN同步A序列号的作用。

  • 终止标志位FIN: 表示发送方已经没有数据需要发送,请求释放TCP连接。
    FIN 标志位的作用是保证 TCP 连接的正常关闭。在 TCP 连接关闭时,发送方和接收方都需要发送 FIN 标志位的 TCP 报文,以请求关闭连接。通过使用 FIN 标志位,TCP 协议可以保证连接的正常关闭,避免数据的丢失和不可靠性。

需要注意的是,TCP 连接关闭时可能会出现 TIME_WAIT 状态。在 TCP 连接关闭后,发送方和接收方都需要等待一段时间,以确保对方已经收到了所有数据,并且确认了连接的关闭。这个等待时间称为 TIME_WAIT 状态。在 TIME_WAIT 状态下,TCP 连接不能被重新建立

TCP 首部格式和 TCP 连接是密切相关的。TCP 首部中的信息用于控制和管理 TCP 连接和数据传输,而 TCP 连接则是基于 TCP 首部中的信息建立的。在进行 TCP 数据传输时,需要使用 TCP 首部来控制和管理数据的传输过程,以确保数据的可靠性和正确性。
接下来我们将从三次握手和四次挥手过程中具体了解TCP首部格式的使用。

3、三次握手

TCP 建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP 报文段,称之为“三次握手”,采用三次握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。这个连接必须是一方主动打开,另一方被动打开的。

3.1 “三次握手”过程详细介绍

以下为客户端主动发起连接的图解:
三次握手
最初两端的TCP进程都处于关闭状态,握手之前主动打开连接的客户端(Client)结束CLOSED阶段,被动打开的服务器端(Server)也结束CLOSED阶段,并进入LISTEN监听阶段,等待TCP客户进程的连接请求。

  1. Client向Server发送TCP连接请求报文段,并进入同步已发送状态(SYN-SENT)
 标志位SYN=1,表示“请求建立新连接”;
 序号seq=x,作为初始值;
  1. Server收到TCP连接请求报文段后,如果同意建立连接,则向Client发送TCP连接请求确认报文段,并进入同步已接收状态(SYN-RCVD)
 标志位SYN=1、ACK=1,表示“确认Client的报文之后,结束LISTEN阶段,同意创建新连接”;
 序号seq=y,作为初始值;
 确认号Ack=x+1,表示“收到Client的序号seq=x,并将其值加1作为自己确认号Ack的值,这是对Client所选择的初始序号seq的确认;
  1. Client接收到Server确认收到数据的TCP报文之后,明确了数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP确认报文段,并进入连接已建立状态(ESTABLISHED)
 标志位ACK=1,表示”确认收到Server同意连接的确认号Ack;
 序号seq=x+1,因为Client发送的第一个报文段序号为x,并且不携带数据,因此第二个报文段的序号为x+1;
 确认号Ack=y+1,表示“收到Server序号seq=y,并将其值加1作为自己确认号Ack的值;

注意: TCP规定,普通的TCP确认报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下所发送的下一个数据报文段的序号仍是x。所以第三次Client发送报文段的时候,原seq=x不变,在此基础上直接+1即可。

Server收到来自Client的“确认收到服务器数据”的TCP报文之后,明确了数据传输是正常的。Server结束SYN-SENT阶段,进入ESTABLISHED阶段
此后客户端和服务器端进行正常的数据传输,这就是“三次握手”的过程。

3.2 为什么要进行第三次握手?

由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如Client发起了SYN=1创建连接的请求(第一次握手)。如果Server就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给Client,这个数据包因为网络传输的原因丢失了,丢失之后Client就一直没有接收到服务器返回的数据包。
Client可能设置了一个超时时间,时间到了就关闭了连接创建的请求。再重新发出创建连接的请求,而Server是不知道的,如果没有第三次握手告诉Server,Client收的到传输的数据的话,Server是不知道对方有没有接收到自己返回的信息的。

也可以这样理解:“第三次握手”是Client向Server发送数据,这个数据就是要告诉服务器,Client有没有收到服务器“第二次握手”时传过去的数据。若发送的这个数据是“收到了”的信息,接收后服务器就正常建立TCP连接,否则建立TCP连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。
在这里插入图片描述

4、四次挥手

4.1 “四次挥手”过程详细介绍

挥手之前主动释放连接的Client结束ESTABLISHED阶段。随后开始“四次挥手”
在这里插入图片描述

  1. 首先Client想要释放连接,向Server发送一段TCP报文
 标记位FIN=1,表示”请求释放连接“;
 序号seq=u,设为初始值;
 随后Client客户端进入`FIN-WAIT-1阶段,即半关闭阶段`。并停止发送数据给Server,`但Client这边仍然可以收到Server发送过来的数据`;
  1. Server端接收到从Client发出的TCP报文之后,确认了客户端想要释放连接,随后Server结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)
标记位ACK=1,表示”接收到Client发送的释放连接的请求“;
序号seq=v
确认号Ack=u+1
Client收到Server发过来的报文后,进入`FIN-WAIT-2阶段`;

前"两次挥手"既让Server知道了Client想要释放连接,也让Client知道Server了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了。

  1. Server自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放连接准备,再次向客户端发出一段TCP报文
标志位FIN=1、ACK=1,表示”已经准备好释放连接了“;
序号seq=w;
确认号Ack=u+1;

随后Server端结束CLOSE-WAIT阶段,进入LAST-ACK阶段(最后确认)。并且停止向Client发送数据,但是仍然能够接收从对方传输过来的数据。

  1. Client收到从Server端发出的TCP报文,确认了Server已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向Server发送一段报文
标记位ACK=1,表示”收到了Server准备好释放连接的信号“;
序号seq=u+1;
确认号Ack=w+1
随后Client在TIME-WAIT阶段等待`2MSL`

为什么Client要等待2MSL?
当客户端发出最后的ACK确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。MSL指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。

Server收到从Client发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭连接。
Client等待完2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,由此完成“四次挥手”。

后“两次挥手”既让Client知道了Server准备好释放连接了,也让Server知道了对方了解自己准备好释放连接了。于是,可以确认关闭连接,由此完成“四次挥手”。

4.2 为什么“握手”是三次,“挥手”要四次?

TCP建立连接时之所以只需要"三次握手",是因为SYN建立连接报文与ACK确认接收报文是在同一次"握手"当中传输的,所以"三次握手"不多也不少,正好让双方明确彼此信息互通。
TCP释放连接时之所以需要“四次挥手”,是因为FIN释放连接报文与ACK确认接收报文是分别由第二次和第三次"握手"传输的。释放连接时,被动方服务器突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。所以是“三次握手”,“四次挥手”。
以上就是小编对TCP连接的建立与释放的理解,如有不当之处,欢迎大家指正。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值