计算机网络——TCP 协议的三次握手 / 四次挥手

简述

TCP / UDP 协议都是传输层的协议。

UDP 是面向无连接的协议,就是说发送端不在乎消息数据是否传输到接收端了,所以会出现数据丢失的情况,所以可靠性也不高。

TCP 是面向连接的、可靠的、基于字节流的传输层协议。所谓面向连接的,就是必须发送端和接收端必须处于连接状态才能发送数据。可靠的就是无论网路链路出现的什么变化,都可以保证一个报文能够到达接收端。

字节流:用户消息通过 TCP 协议传输时,消息可能会被操作系统分组成多个 TCP 报文,如果接收方的程序如果不知道消息的边界,是无法读出一个有效的用户消息的。

TCP 建立连接

TCP 是面向连接的,所以传输数据前需要和接收端建立连接,通过三次握手来进行。过程如下图:

图片来源: 小林coding

简单描述一下三次握手:

1. 客户端首先初始化自己的序列号,发送带有 SYN 标识的报文给服务端,表示向服务端发起连接。客户端进入 SYN-SEND 状态。

2. 服务端接收到报文之后,同样初始化自己的序列号,同时将确认应答的序列号,也就是收到的客户端的序列号 + 1,返回给客户端发送带有 SYN + ACK 标识的报文,表示我接收到了你的连接请求,并同意连接。服务端进入 SYN-RCVD 状态。

3. 客户端接收到了服务端发来的应答,将收到的客户端的序列号 + 1,再次向服务端发送带有 ACK 表示的报文,表示我接收到你发的应答了,确认进入连接状态。这次握手是可以携带客户端到服务端的数据。客户端进入 ESTABLISHED 状态,在服务端收到客户端的应答之后也进入 ESTABLISHED 状态。

用一个例子来描述三次握手的情况。

为什么是三次握手

主要原因:三次握手是为了阻止重复历史连接的初始化。

设想一个场景,当客户端向服务端发送一个请求连接的报文之后宕机了,报文在到达服务器前被网络阻塞了,此时服务器并没有收到连接请求,状态没有变化。然后客户端重启之后,再次向服务端发送连接的报文。会出现下面的情况。

假设此时旧的请求报文比新的先到达服务端,然后向客户端发送应答报文,都知道,报文里是包含了客户端的序列号的,假设初始序列号是10,而服务端返回的是11(10+1),而客户端在重启之后发送的序列号是20,所以客户端现在期望收到的报文序列号应该是21(20+1),但是此时收到的是11,那么就会向服务端发送 RST 请求报文, 表示出现了历史连接,此次连接中止。(有内鬼,中止交易)。

而后一段时间之后,新发送的连接请求报文到达服务端,之后就会进行正常的 TCP 连接。用一个图来简单描述一下。

那么两次握手能不能解决历史连接的问题呢。

假设两次握手,那么第一次握手服务端收到客户端的SYN 之后,就进入到了 ESTABLISHED 状态,此时服务端是可以向客户端发送数据了,但是这个时候客户端还没有进入到 ESTABLISHED 状态。服务端向客户端发送 SYN+ACK 的报文之后,客户端如果判断此次是历史连接,那么会回复 RST 中断连接。但在这个期间,如果服务端发送了数据,那么发送的数据可能就丢失了,还浪费了资源。

三次握手之所以能解决历史连接的问题,就是因为如果这是历史连接,在第二次握手时服务端并不会进入到 ESTABLISHED 状态,也就不能发送数据给客户端,不会白白浪费资源。而是在客户端确认了不是历史连接的之后转变状态。

其他原因:同步初始序列号,避免浪费资源

1. 第一次握手,客户端向服务端发送报文。

2. 第二次握手,服务端向客户端发送报文,确认了客户端发送正常,服务端接收正常。

3. 第三次握手,客户端最后向服务端应答报文,确认了服务端发送正常,客户端接收正常。

由此确认了客户端和接收端连接正常。因为握手是会交换序列号的,也就是同步序列号,序列号在传输数据时去除重复的数据,可以根据序列号按序接收。

而两次握手不能确保序列号同步,同时不能确认是否连接正常,假如只有两次握手,少了第三次握手,那么服务端不知道客户端的接收是否正常,如果不正常,那么服务端发送的数据就会丢失,浪费了资源。

握手过程中出现了报文丢失怎么办

当第一次握手丢失了,当客户端向服务端第一次握手,然后客户端迟迟收不到服务端的 SYN+ACK 的报文,就会触发超时重传,重传的报文序列号是一样的。

而超时时间和重传次数也有限制,不可能一直让客户端发送连接请求,浪费资源,在Linux 里,重传次数是 5 ,而每次超时时间是上一次的两倍,一般第一次是 1秒,第二次就是2秒,以此类推,5次重传总耗时就是 1+2+4+8+16+31 = 63秒,大约一分钟,如果5次都丢失,那么就不会再进行连接了。

第二次握手丢失。第二次握手包含了给客户端的回应报文 ACK,和服务端发起建立连接的请求报文 SYN ,如果丢失了,客户端会以为第一次握手丢失了,那么会触发超时重传。正常情况下,客户端接收到第二次握手之后会发送 ACK 响应报文给服务端,但是服务端迟迟都收不到,那么服务端也会触发超时重传机制。

第三次握手丢失。第三次握手是客户端发送给服务端的响应报文,如果丢失了,服务端会认为第二次握手丢失了,所以服务端会触发超时重传机制。

TCP 断开连接的四次挥手

TCP 建立连接时需要发送报文,断开连接时同样需要发送报文。

1. 首先客户端想要断开连接,会发送一个带有 FIN 标识的请求报文给服务端。客户端进入 FIN_WAIT_1 状态。

2. 服务端接收到报文之后会回复给客户端一个带有 ACK 标识的应答报文。服务端进入 CLOSE_WAIT 状态。客户端接收到 ACK 报文之后进入 FIN_WAIT_2 状态。

3. 因为想要断开连接时服务端可能还有数据没有处理完,所以需要等待处理完成,处理完成之后会发送带有 FIN 标识的请求报文给客户端。服务端进入 LAST_ACK 状态。

4. 客户端接收到报文之后最后返回带有 ACK 标识的应答报文给服务端,客户端进入 TIME_WAIT  状态。服务端接收到ACK 报文之后进入到 CLOSE 状态。一段时间之后,客户端会进入 CLOSE 状态,双方都关闭连接。

图片来源 小林coding

可以用打电话的方式来打个比方。

为什么要挥手四次

从每次挥手发送带有标识的报文可以看出来,关闭连接时,客户端向服务端发送 FIN 报文,只是代表客户端已经发送数据完毕了,但是还能接收数据,同样的服务端也是这样。

服务端收到 FIN 报文时,回复一个 ACK 应答报文,表示我收到了你的请求,但是你先等等,我还有数据没处理完,等到我数据处理完了,我再发送客户端一个 FIN 报文表示我也没数据需要处理和发送了。

假设少了一次挥手,比如说服务端只发送了 ACK 报文,客户端就关闭连接的话,会导致还未处理和发送的数据出现错误或者丢失。

不过,在特定情况下,可以将四次挥手合并成三次挥手。比如服务端也没有数据处理和发送时,TCP 存在延迟确认机制且是默认开启的,那么第二次和第三次就会合并,变成三次挥手。

挥手丢失的话会发生什么

和握手相同,如果握手丢失了,发送方迟迟收不到回应,就会认为刚刚的报丢失了,就会触发超时重传机制。同样的是 ACK 报文是不会重传的,假如第二次挥手丢失了,那么客户端收不到 ACK 应答报文,那么就会认为FIN 报文丢失了,那么就会重传 FIN 报文。

简单来说,当前最近的 FIN 报文发送方会经常重传 FIN 报文。

为什么第四次挥手客户端需要等待 2*MSL(报文最长寿命)时间后才进入 CLOSE 状态

在第三次挥手时,服务端会发送 FIN 报文给客户端,关闭连接,但是如果出现了第三次或者第四次挥手丢失的情况,服务端都会触发超时重传机制来重新发送 FIN 报文。

MSL 一个片段在网络中最大的存活时间,2MSL 就是一个发送和一个回复所需的最大时间,如果这个大于这个时间客户端还没有收到服务端重新发送的 FIN 报文,那么客户端就认为服务端已经接收到了自己发送的 ACK 应答报文,然后进行 CLOSE 状态,代表 TCP 连接完成中断。

  • 40
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: TCP三次握手四次挥手TCP协议建立和关闭连接时所采用的步骤。 三次握手是在客户端和服务器之间建立TCP连接时的过程。首先,客户端向服务器送一个请求连接的数据包,该数据包包含一个随机生成的序列号(SYN),表示客户端希望建立连接。服务器接收到该请求后,向客户端回复一个确认连接的数据包,该数据包包含其自己生成的一个随机序列号(SYN-ACK),表示服务器同意建立连接。最后,客户端再次向服务器送一个确认连接的数据包,该数据包中包含服务器的序列号加一(ACK),表示客户端接受服务器的连接请求。这样,TCP连接就建立起来了。 四次挥手是在客户端和服务器关闭TCP连接时的过程。首先,客户端送一个关闭连接的请求数据包(FIN),表示客户端想要关闭连接。服务器收到该请求后,向客户端回复一个确认关闭连接的数据包(ACK),但自己的数据可能没有送完毕。服务器等到自己的数据送完毕后,送一个自己的关闭连接请求数据包(FIN),表示服务器也希望关闭连接。客户端收到服务器的请求后,回复一个确认关闭连接的数据包(ACK),然后等待一段时间,确保服务器收到了该数据包。最后,客户端和服务器都关闭连接,四次挥手过程完成。 通过Wireshark抓包分析TCP三次握手四次挥手可以观察到每个数据包的源地址、目标地址、序列号、确认号等信息。可以通过Wireshark的过滤功能筛选出TCP协议相关的数据包进行分析。通过分析数据包的交互过程,可以确认连接建立和关闭的状态是否符合预期,并可以进一步分析网络延迟、丢包等问题。 综上所述,Wireshark抓包分析TCP三次握手四次挥手可以帮助我们深入理解TCP连接的建立和关闭过程,以及网络故障的根源。 ### 回答2: TCP是一种常用的传输层协议,它通过进行三次握手来建立连接,并进行四次挥手来终止连接。 三次握手的过程如下: 1. 客户端送一个SYN标志位的TCP报文段给服务器,表示请求建立连接; 2. 服务器收到请求后,回复一个带有SYN和ACK标志位的TCP报文段给客户端,表示同意建立连接; 3. 客户端收到服务器的回复后,再次送一个带有ACK标志位的TCP报文段给服务器,表示连接建立成功。 四次挥手的过程如下: 1. 客户端送一个FIN标志位的TCP报文段给服务器,表示希望断开连接; 2. 服务器收到请求后,回复一个带有ACK标志位的TCP报文段给客户端,表示确认收到断开请求; 3. 服务器完成数据送后,送一个带有FIN标志位的TCP报文段给客户端,表示自己也要断开连接; 4. 客户端收到服务器的断开请求后,送一个带有ACK标志位的TCP报文段给服务器,表示确认断开,并进入TIME_WAIT状态。 在三次握手的过程中,第一次握手是客户端起的,第二次握手是服务器回复同意建立连接,第三次握手是客户端回复确认连接。这个过程是为了确保双方都同意建立连接,以保证数据传输的可靠性。 在四次挥手的过程中,首先客户端送断开请求,服务器回复确认,然后服务器送断开请求,客户端回复确认。这个过程是为了保证双方都断开连接,并确保数据完整性。 Wireshark是一款网络抓包分析工具。使用Wireshark可以捕获网络数据包,并对数据包进行解析和分析。通过Wireshark,我们可以看到每个TCP报文段的具体内容,并对三次握手四次挥手的过程进行详细分析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值