【计算机网络专题】四次挥手相关问题(必看题)

本问题对应的项目链接:高频题回答模版训练

PS:这个问的太多了,重点得理解吧,有时候具体细节忘了也没事的

1、说一下四次挥手的过程?

2、什么需要四次呢?

3、time-wait干嘛的,close-wait干嘛的,在哪一个阶段?

4、状态CLOSE_WAIT在什么时候转换成下一个状态呢?

5、为什么 TIME-WAIT 状态必须等待 2MSL 的时间呢?

6、服务端主动发起关闭还是客户端主动发起关闭TCP?

共以下 2 个回答

  • Everglow 永久会员 2023年11月4日 下午12:01
    1、说一下四次挥手的过程?

    假设客户端为主动断开的一方,服务端是被动断开的一方

    第一次挥手:客户端通过系统调用close()/shutdown() 主动断开连接,并向服务器发送fin报文,状态从established -> fin_wait1

    第二次挥手:服务器收到fin报文后会立刻回复一个ack,状态从established -> close_wait ,服务器收到该ack后状态从fin_wait1 -> fin_wait2

    第三次挥手:服务器主动调用close()/shutdown() 主动断开连接,并发送fin,状态从close_wait -> last ack

    第四次挥手:客户端对服务器发送的fin进行ack,状态从 fin_wait2 -> time_wait 并经过2MSL后关闭连接,服务器收到ack后 状态从last ack -> closed

    2、什么需要四次呢?

    四次挥手主要原因是,客户端主动发起断开连接的请求后,服务器可能仍有数据需要处理和发送,所以需要等待服务器处理完数据后,主动调用断开函数,所以服务端的ack 和fin需要分开发送,就需要四次挥手。

    但在特定情况下也会出现三次挥手,第二次和第三次合并成一次,前提是服务器内核开启了TCP延迟确认机制,并且没有数据发送,就会发送一个fin ack

    3、time-wait干嘛的,close-wait干嘛的,在哪一个阶段?

    time-wait是主要有两个作用

    a. 防止已经关闭连接的历史报文发送到相同四元组的新连接中去并且该报文的序列号出现在服务端的接受窗口内造成数据混乱,因为time-wait的时间为2MSL,他可以让两个方向上的数据包都被丢弃,再出现的数据一定是新连接产生的。

    b. 保证被动关闭的一方,能正确的关闭,如果time-wait设置很短或者没有,客户端在收到第三次挥手并发送ack后就会立刻进入close状态,如果ack在网络中丢失了,服务端就会重传fin,此时客户端已经处于close状态,就会发送一个rst,服务端收到这个rst会解释出一个错误,虽然也会关闭连接,但这样的关闭并不优雅,所以设置为2MSL的时间正好是客户端ack到服务器,服务器的fin到客户端的时间,如果客户端再次收到fin就会重置time-wait

    close-wait的作用就是保证服务器有足够的时间处理和发送数据,等待应用层主动调用关闭连接函数,才会发送fin,表示服务器也可以断开连接。

    4、状态CLOSE_WAIT在什么时候转换成下一个状态呢?

    同上。

    5、为什么 TIME-WAIT 状态必须等待 2MSL 的时间呢?

    同上。

    6、服务端主动发起关闭还是客户端主动发起关闭TCP?

    都可以,tcp连接两端谁先主动调用关闭连接函数,或者进程异常退出,就代表谁主动关闭tcp。

    0 赞同 0 条回复
  • 秊 永久会员 2023年9月14日 下午6:15

    1、说一下四次挥手的过程?

    首先要说明,通信双方都可以主动断开连接,下面以客户端主动断开连接为例:

    第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT_1 状态。

    第二次挥手:服务端收到 FIN 之后,会把客户端的序列号值 + 1 作为 ACK 并发送,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。

    之后客户端接收到服务端发送的 ACK,进入 FIN_WAIT_2 状态

    第三次挥手:等服务端处理完数据后,想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。

    第四次挥手:客户端收到 FIN 之后,一样会将服务端的序列号值 + 1 作为自己 ACK 报文的序列号值回应,此时客户端处于 TIME_WAIT 状态,并在等待 2MSL 时间后,会自动进入 CLOSE 状态,至此客户端完成连接的关闭。

    之后服务端收到客户端的 ACK 之后,就进入了 CLOSE 状态,至此服务器端完成连接的关闭。

    2、什么需要四次呢?

    需要四次的原因在于,四次挥手中的第二三次挥手是将三次握手中的第二次握手给分开了。第二次握手中是服务端将 SYN 和 ACK 合并到一个包中发送,第二三次挥手是服务端先发送 ACK,处于 CLOST_WAIT 状态,等处理完数据后,再发送 FIN,继续断开连接的过程。

    至于为什么需要等待服务端处理完数据这个过程,原因在于 TCP 是全双工通信,在客户端希望断开连接时,服务端可能还有数据处理或者发送,也就是此时还不能立马关闭服务端到客户端的数据通道,所以就不能在第二次挥手时将 FIN 和 ACK 一起发出。必须是先回应一个 ACK,等处理完数据后,再发送 FIN 包。

    3、TIME-WAIT 干嘛的,CLOSE_WAIT干嘛的,在哪一个阶段?

    需要 TIME_WAIT 状态简单说就两个原因:一个是优雅的关闭 TCP 连接,也就是尽量保证被动关闭的一端能够收到它自己发出去 FIN 报文的 ACK 确认报文。另一个是处理延迟的重复报文,避免连续两个使用相同四元组的连接,前一个的报文干扰后一个连接。以上两个目的都是由主动断开的的一方在 TIME_WAIT 状态等待 2MSL 时间来保证的。

    第一个目的比较好理解,理论上 1MSL 的时间就足够确定被动关闭端已经接收到了 ACK 值。第二个目的的话,先等第一个 MSL 确保主动关闭端发出的最后一个 ACK 值从网络中消失,再等第二个 MSL 是为了防止对端在收到这个 ACK 前的一刹那时间可能触发重传机制,等这个重传的 FIN 报文消失的时间也需要 1MSL,总共就是 2MSL。

    CLOSE_WAIT 状态需要的原因就是 TCP 为什么需要四次握手而不是三次握手的原因,主要就是在一二次挥手后,服务端可能还有遗留的数据需要处理,也就是需要确保数据的完整性。在处理完之后会主动向客户端发送 FIN 报文,进入 LAST_ACK 状态。

    4、服务端主动发起关闭还是客户端主动发起关闭TCP?

    都可以,主动关闭的一端会有 TIME_WAIT 状态,被动关闭的一端有 CLOSE_WAIT 状态。

    0 赞同 0 条回复

# 回答此问题

后才能回答