码农的情书:TCP四次挥手,如何优雅地跟她说再见

想必进来的友友们都是有一颗向往浪漫的心,那么刚好现在春招就一起来复习TCP的四次挥手吧,努力早日和她过上美好的生活。

本文主要从前端需要了解的角度,来聊一聊TCP四次挥手,本人还在学习。文章可能有一些,不严谨不恰当的地方还请批评指正。

四次挥手告别💕

在一个名为“深城”的一线城市中,住着一位名叫“小T”的程序猿。小T有一段特别的感情经历,与他的“女神”——数据包小姐。

他们的相遇始于一次热情洋溢的三次握手。小T通过精心准备的信息(SYN),向数据包小姐发出了初次问候。她收到后回应了一个确认信息(SYN+ACK),让小T的心中小鹿乱撞。最后,他回复一个确认(ACK),两人的关系就此建立,开始了愉快的数据传输之旅。

然而,天下没有不散的宴席,随着任务完成,小T意识到是时候结束这段连接了。于是,他鼓足勇气,开始了一场独特且充满尊重的告别仪式。阅卷

第一步,小T寄出一封告别信(FIN),表示自己已经没有新的内容要分享了,但仍然愿意聆听她的回应。数据包小姐收到了这封告别信,虽然心中有万般不舍,但她成熟地回应了一个确认(ACK),表示理解并尊重小T的决定。

接下来的时间里,数据包小姐完成了自己手头的工作,整理好了所有的心情和数据,终于,在某个宁静的午后,她也向小T发出了一封告别信(FIN)。小T读完后,深感感动与敬佩,立即回复了一份确认(ACK)。

就这样,他们两人用各自的方式表达出对彼此的尊重与珍视,完成了这场优雅的“四次挥手”。尽管连接已断,但那份曾经共享的时光和深深的理解,却如同印记一般永存于他们心中。🥰

码农的情书:TCP四次挥手,如何优雅地跟她说再见

真正的四次挥手😁

看完浪漫的小故事,我们一起来复习真正的TCP四次挥手吧😘

首先需要了解几个专有名词

  1. 报文:在网络通信中,TCP报文是包含有控制信息(如TCP首部)和实际数据的数据包。
  2. Seq:序列号,TCP协议为每个发送的数据段分配唯一序列号,帮助接收端识别和重组数据顺序。
  3. ISN:初始序列号,TCP连接建立时使用的一个随机数,用于新连接的起始序列号计算,防止混淆,使用ISN(Initial Sequence Number)算法生成。
  4. ack:确认号,接收端反馈给发送端,表示已成功接收至哪个序列号为止的数据。
  5. ACK标志:TCP报文头中的一个标志位,若设置为1,则表示此报文用于确认已接收的数据。
  6. SYN标志:在连接建立阶段使用,SYN=1表示请求或响应建立连接,并携带ISN。
  7. FIN标志:用于终止连接,FIN=1表示一端不再发送数据,请求关闭连接。

码农的情书:TCP四次挥手,如何优雅地跟她说再见

图解可能有点难理解我们继续从情景出发

第一次挥手

情景:

首先是小T觉得是时候要告别了,然后向数据包小姐发了一份离别信(FIN报文)。

当发送消息的时候,小T在等待数据包小姐的对他发送的消息的回应,这个等待的时间段就被称为FIN_WAIT_1

第一次挥手(客户端发起关闭)

客户端发起关闭(表示客户端没有数据要发送了,请求关闭连接)

客户端 —FIN,ACK(seq=u,ack=v+1)—> 服务端

假设此时的seq = u ,ack = v+1

1. 客户端状态:

  • 发送FIN报文之后客户端进入FIN_WAIT_1状态等待服务端对FIN报文的确认

2. 服务端状态:

  • 此时服务端接受客户端的FIN报文,但是还没有关闭连接,因为可能还存在未发送完的数据

第二次挥手

当我们的数据包小姐收到小T的告别信(FIN报文),马上就回了一句”好的,我尊重理解你的想法”(ACK报文)。

接下来数据包小姐,继续整理自己手头上未完成的工作,为最后的别离做好准备,这个准备的时间就是服务端的CLOSE_WAIT

此时小T也在等待数据包小姐姐的最后的信息,这个等待时间也就是客户端的FIN_WAIT2

第二次挥手(服务端确认,并可能继续发送数据):

客户端 <—ACK(seq=v,ack=u+1)— 服务端

1.客户端状态

客户端接受服务端对ACK报文的确认之后,进入FIN_WAIT_2状态,等待服务端发送FIN报文

2. 服务端状态

  • 服务端回应一个ACK报文,表示收到客户端的关闭请求,进入第二次挥手
  • 服务端进入ClOSE_WAIT状态,准备关闭连接,同时还可以继续发送剩余数据
  • 如果没有要发送的剩余数据,则向客户端发送FIN报文进入第三次挥手

码农的情书:TCP四次挥手,如何优雅地跟她说再见

第三次挥手

情景:

当数据包小姐整理了心情,处理完成了手头上的工作,也写了一封告别信给小T(FIN报文),
然后她等待着小T的确认,这个等待时间就是服务端的LAST_ACK;

码农的情书:TCP四次挥手,如何优雅地跟她说再见

第三次挥手(服务端发起关闭)

客户端 <—FIN,ACK(seq=w,ack=u+1)— 服务端,

w与v之间的关系,发送了新的数据之后,v就会增加,如果服务端没有再次发送数据在第二次挥手中,那么w=v

服务端状态

服务端发送FIN报文给客户端
表明服务端不再发送数据准备关闭,
进入LAST_ACK状态,等待客户端对FIN报文的确认

第四次挥手

情景:

当小T收到数据包小姐姐的告别信(FIN报文)之后,如释重负,立即回复了一封信(ACK报文)表示确认。

当数据包小姐姐收到小T断开联系的确认之后立即断开了与小T的联系,也就是图示中服务端的CLOSED

小T又怕数据包小姐没收自己的确认,怕她傻傻的等待,然后又发消息给他;于是小T一直等了2MSL,这个等待时间也就是图示中的TIME_WAIT,确保数据包小姐收到确认信(ACK报文)之后才断开联系。

第四次挥手(客户端确认服务端的关闭)

客户端 —ACK(Seq = u+1 , ack =w+1 )—> 服务端

1.客户端状态

客服端往服务端发送ACK确认,然后进入TIME_WAIT状态,超长等待状态
等待一段时间通常是两倍报文最大生存时间2MSL

期间没有其他问题就进入CLOSED状态

2. 服务端状态

服务端一旦收到客户端对报文的ACK确认,立即进入CLOSED状态彻底关闭连接

码农的情书:TCP四次挥手,如何优雅地跟她说再见

面试官问题

1. 为什么是四次挥手呢

因为服务端在接收到 FIN , 往往不会立即返回 FIN , 必须等到服务端所有的报文都发送完毕了,才能发 FIN 。因此先发一个 ACK 表示已经收到客户端的 FIN ,延迟一段时间才发 FIN 。这就造成了四次挥手。 如果是三次挥手会有什么问题? 等于说服务端将 ACK 和 FIN 的发送合并为一次挥手,这个时候长时间的延迟可能会导致客户端误以为 FIN 没有到达客户端,从而让客户端不断的重发 FIN

2. 为什么客户端最后会等待2MSL这么长时间呢

  1. 确保服务端接受到客户端的ACK报文
    如果ACK丢失,服务端将在超时之后重新发送FIN报文,客户端在TIME_WAIT期间还可以从发ACK报文
  2. 保护服务端正常关闭,如果服务端因为ACK丢失而没有确认,服务端会继续保持中间状态,等待2MSL,有足够时间确保服务端关闭

关于计算机网络的话,想必各位刚入门前端的友友都会和我一样,有点懵,我一个切页面的为啥还需要知道计算机网络的知识。但是行情越来越卷,面试中也要求我们前端从业者需要会更多技能。

本人目前在准备春招,也希望和一起准备春招的佬们互相交流一下,一起冲刺大厂,欢迎私信评论或交流

原文链接:https://juejin.cn/post/7341207809356857359 作者:GuanYi

(0)
上一篇 2024年3月4日 下午4:00
下一篇 2024年3月4日 下午4:11

相关推荐

发表评论

登录后才能评论