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

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

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

四次挥手告别💕

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

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

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

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

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

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

真正的四次挥手😁

看完浪漫的小故事,我们一起来复习真正的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表示一端不再发送数据,请求关闭连接。

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

第一次挥手

情景:

首先是小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报文进入第三次挥手

第三次挥手

情景:

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

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

客户端 <---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状态彻底关闭连接

面试官问题

1. 为什么是四次挥手呢

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

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

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

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

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

相关推荐
_AaronWong8 分钟前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode8 分钟前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户54330814419417 分钟前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo21 分钟前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭1 小时前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木1 小时前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮1 小时前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github
UrbanJazzerati1 小时前
Vue3 父子组件通信完全指南
前端·面试
是一碗螺丝粉1 小时前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain
wuhen_n1 小时前
双端 Diff 算法详解
前端·javascript·vue.js