TCP三次握手和四次挥手

TCP协议通过三次握手建立连接,确保双方序列号的同步和连接可靠性;四次挥手则用于断开连接,确保数据传输完毕后双方都能关闭连接。在挥手过程中,TIME_WAIT状态等待2MSL是为了防止旧数据干扰新连接,并确保服务器接收到确认。三次握手避免了半连接状态的安全风险,四次挥手则是因关闭连接时双方可能仍有数据待发送。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接

一.用到的相关术语

1)序号:小写字母
序列号 seq
确认号 ack

2)标志位:大写字母,其值要么为1 ,要么为 0
确认 ACK
同步 SYN
终止 FIN

二、TCP三次握手过程:

第一次握手:Client 将标志位 SYN 置为1,随机产生一个值 seq=x,并将该数据包发送给 Server,Client 进入SYN_SENT 状态,等待 Server 确认。
第二次握手:Server 收到数据包后由标志位 SYN=1 知道 Client 请求建立连接,Server 将标志位 SYN 和 ACK 都置为1,ack=x+1(表示需要 Client 下一次从哪个字节开始发送数据),随机产生一个值 seq=y,并将该数据包发送给Client 以确认自己已经收到了连接请求,Server 进入 SYN_RCVD 状态。
第三次握手:Client 收到确认应答后,检查 ack 是否为 x+1,ACK是否为 1,如果正确,则将标志位 ACK 置为 1,ack=y+1,并将该数据包发送给Server,然后Client 进入ESTABLISHED状态,完成三次握手,随后 Client 与 Server 之间可以开始传输数据了。

三次握手图示:

在这里插入图片描述

三、TCP 四次挥手过程:

第一次挥手:Client 发送一个FIN,用来关闭 Client 到 Server 的数据传送,Client 进入 FIN_WAIT_1 状态。
第二次挥手:Server 收到 FIN 后,发送一个 ACK 给Client,确认序号为收到的序号值+1(与 SYN 相同,一个 FIN 占用一个序号),Server 进入CLOSE_WAIT 状态。
第三次挥手:Server 发送一个 FIN ,用来关闭 Server 到 Client 的数据传送,Server 进入LAST_ACK状态。
第四次挥手:Client 收到 FIN 后,Client 进入 TIME_WAIT 状态,接着发送一个 ACK 给 Server,确认序号为收到的序号值+1,Server 进入 CLOSED 状态,完成四次挥手。

四次挥手图示:

在这里插入图片描述

四、相关面经总结:

1.为什么需要三次握手,而不是二次握手?

  • 为了实现 TCP 的可靠数据传输, TCP 协议的通信双方, 都必须维护一个自己的序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到了,哪些对方没有收到。 三次握手的过程即是通信双方相互告知对方自己序列号的起始值, 并确认对方已经收到了自己的序列号起始值的必经步骤。
  • 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 而另一方的起始序列号,则得不到确认,因此就违背了 TCP 的可靠性原则。
  • 为了实现可靠传输,发送方和接收方始终需要同步( SYN)自己的序号。 需要注意的是, 序号并不是从 0 开始的, 而是由发送方随机生成的一个初始序列号 ( ISN )开始的。 由于 TCP 是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此,通信双方都需要随机产生一个初始的序列号, 并且把这个初始序列号的值告诉对方,对方收到后就要应答,因此需要三次握手。

2.第三次握手失败后怎么处理?

如果此时 ACK 在网络中丢失,那么 Server 端该 TCP 连接的状态为SYN_RECV,并且依次等待3秒、6秒、12秒后重新发送 SYN+ACK 包,以便Client 重新发送 ACK 包。Server 重发 SYN+ACK 包的次数,默认值为5,但可以修改。如果重发指定次数后,仍然未收到 ACK 应答,那么一段时间后,Server 自动关闭这个连接。但是 Client 认为这个连接已经建立,如果这时 Client 端向 Server 写数据,Server 端将以 RST 标志位响应,此时 Client 方能感知到Server 的错误。

3.为什么连接的时候是三次握手,关闭的时候却是四次挥手?

Server 在 LISTEN 状态下,收到建立连接请求的 SYN 的报文后,可以直接把ACK 和 SYN 放在一个报文里发送给 Client,其中ACK报文是用来应答的,SYN报文是用来同步的,因此是三次握手。
而关闭连接时,当收到对方的 FIN 报文时,仅仅表示对方不再发送数据了但是对方还可以接收数据,己方也未必全部数据都已经发送给对方了,所以己方既可以立即关闭连接,发送 FIN 包,也可以发送一些数据给对方后,再发送 FIN 报文给对方,来表示自己现在请求关闭连接,因此,己方 ACK 和 FIN 一般都会分开发送,所以关闭时候是四次挥手。(关闭连接时,当 Server 端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉 Client端,“你发的 FIN 报文我收到了”。只有等到我 Server 端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送,故需要四步握手。)

4.为什么 TIME_WAIT 状态需要经过 2MSL(最大报文段生存时间) 才能返回到CLOSE 状态?

MSL即Maximum Segment Lifetime,就是最大报文生存时间,是任何报文在网络上的存在的最长时间,超过这个时间报文将被丢弃。

  • Client 的最后一个 ACK 报文在传输的时候丢失,Server 并没有接收到这个报文。这个时候,Server 就会超时重传这个 FIN 消息,然后 Client 就会重新返回最后一个 ACK 报文,等待两个时间周期,完成关闭,Client 进入到 CLOSE 状态。如果不等待这两个时间周期,Server 重传的那条 FIN 消息 Client 可能就不会收到,因此 Client 就不会重传 ACK 了,Server 就会因为接收不到 Client 的 ACK 信息而无法正常关闭。(所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接)
  • 防止“已失效的连接请求所携带的报文段”出现在本连接中。在发送完最后一个 ACK 报文段后,再经过 2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失。这样就可以使下一个新的连接中不会出现这种错误的数据。

5.ISN代表什么?意义何在?

ISN,发送方的字节数据编号的起点。

6.ISN是固定不变的吗?

动态随机。

7.ISN为何要动态随机?

增加安全性,为了避免被第三方猜测到,防止网络攻击。

8.ACK状态位单独能承担这个消息传递的任务吗?

不能!需要有 Acknowledge Number配合才行。
如果我方发出的Acknowledge Number == 10001,那意味着序列号10000及之前的数据已经成功接收。

9.如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文客户端仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值