当前位置: 首页 > news >正文

TCP三次握手与四次挥手详解含图解

最近在复习计网,故总结本文,如有错误请评论区指出

文章目录

    • TCP三次握手:建立可靠连接(核心目的:同步序列号,确认双方收发能力)
      • 三次握手完整流程
        • 第一步:客户端 → 服务器(SYN=1,seq=x)
        • 第二步:服务器 → 客户端(SYN=1,ACK=1,seq=y,ack=x+1)
        • 第三步:客户端 → 服务器(ACK=1,seq=x+1,ack=y+1)
      • 为什么是三次握手,不是两次?
    • TCP四次挥手:断开可靠连接(核心目的:确保双方数据都已传输完成,优雅释放资源)
      • 四次挥手完整流程
        • 第一步:客户端 → 服务器(FIN=1,seq=u)
        • 第二步:服务器 → 客户端(ACK=1,seq=v,ack=u+1)
        • 第三步:服务器 → 客户端(FIN=1,ACK=1,seq=w,ack=u+1)
        • 第四步:客户端 → 服务器(ACK=1,seq=u+1,ack=w+1)
      • 为什么是四次挥手,不是三次?

TCP三次握手:建立可靠连接(核心目的:同步序列号,确认双方收发能力)

三次握手的核心是双向确认:客户端和服务器都要确认“自己能发、也能收”,避免出现“我能发但收不到你消息”“你能收但发不出消息”的情况,最终建立稳定的连接。

先明确两个关键概念:

  • SYN:同步序列号,用于发起连接,告诉对方“我要开始建立连接了,我的初始序列号是X”;

  • ACK:确认应答,用于确认收到对方的消息,告诉对方“我收到你的消息了,下一次你可以发序列号为Y的消息”。

补充:序列号(seq)是TCP可靠传输的关键,用于标识每一个字节的数据,避免数据丢失、重复、乱序——每发送一个字节,序列号就加1,接收方通过序列号确认数据是否完整。

三次握手完整流程

第一步:客户端 → 服务器(SYN=1,seq=x)

客户端主动向服务器发送连接请求报文,核心信息:SYN=1(表示发起连接),初始序列号seq=x(x是随机生成的一个数字,比如1000)。

目的:告诉服务器“我想和你建立连接,我的初始序列号是x,你可以开始准备接收我的数据了”。

此时,客户端状态:SYN-SENT(同步已发送,等待服务器确认)。

第二步:服务器 → 客户端(SYN=1,ACK=1,seq=y,ack=x+1)

服务器收到客户端的连接请求后,会回复一个确认+同步报文,核心信息:

  • ACK=1(表示确认收到客户端的SYN请求);

  • ack=x+1(表示“我已经收到你序列号为x的消息,下一次请你发送x+1及以后的消息”);

  • SYN=1(表示服务器也向客户端发起同步,告诉客户端“我也准备好和你建立连接了”);

  • seq=y(服务器的初始序列号,也是随机生成的,比如2000)。

目的:双向确认的关键一步——既确认自己收到了客户端的请求,也告诉客户端“我能发消息,我的初始序列号是y,你也准备接收我的数据”。

此时,服务器状态:SYN-RCVD(同步已接收,等待客户端最终确认)。

第三步:客户端 → 服务器(ACK=1,seq=x+1,ack=y+1)

客户端收到服务器的回复后,再向服务器发送一个最终确认报文,核心信息:

  • ACK=1(确认收到服务器的SYN+ACK报文);

  • ack=y+1(表示“我已经收到你序列号为y的消息,下一次请你发送y+1及以后的消息”);

  • seq=x+1(客户端的下一个序列号,承接第一步的x,说明客户端已经准备好发送数据)。

目的:告诉服务器“我已经收到你的确认和同步,我这边也完全准备好,连接可以正式建立了”。

此时,客户端状态:ESTABLISHED(连接已建立,可开始传输数据);服务器收到该报文后,状态也变为ESTABLISHED,双方正式进入数据传输阶段。

为什么是三次握手,不是两次?

核心原因:避免“失效的连接请求”被服务器误判,导致资源浪费,同时确保双方收发能力都正常

举个例子:客户端发送的第一个连接请求(SYN=x),因为网络延迟,过了很久才到达服务器——此时客户端已经超时重发了新的请求,并且和服务器建立了连接、传输完数据、断开了连接。而这个延迟的请求到达服务器后,服务器会误以为是客户端新的请求,若只有两次握手,服务器会直接发送SYN+ACK,然后进入连接状态,等待客户端发送数据,但客户端根本没有新的请求,不会回复,服务器会一直占用资源,造成浪费。

三次握手的第三次,就是客户端对服务器的SYN+ACK进行确认,确保双方都知道“对方能收能发”,避免上述问题。

TCP四次挥手:断开可靠连接(核心目的:确保双方数据都已传输完成,优雅释放资源)

四次挥手的核心是双向释放:客户端和服务器都要确认“自己的数据已经全部发送完毕,也收到了对方的所有数据”,才能彻底断开连接,避免数据丢失(比如服务器还在发数据,客户端突然断开,会导致数据丢失)。

补充:断开连接的发起方可以是客户端,也可以是服务器(比如客户端主动关闭浏览器,发起断开请求;或者服务器主动关闭连接),这里以「客户端主动发起断开」为例,拆解流程。

先明确个关键概念:FIN(结束标志),用于发起断开连接,告诉对方“我已经没有数据要发送了,准备断开连接”。

四次挥手完整流程

第一步:客户端 → 服务器(FIN=1,seq=u)

客户端数据传输完成后,主动向服务器发送断开连接请求报文,核心信息:FIN=1(表示发起断开连接),seq=u(u是客户端当前的序列号,即最后一次发送数据的序列号+1)。

目的:告诉服务器“我这边已经没有数据要发送了,你可以准备接收我最后的确认,然后我们断开连接”。

此时,客户端状态:FIN-WAIT-1(终止等待1,等待服务器确认)。

第二步:服务器 → 客户端(ACK=1,seq=v,ack=u+1)

服务器收到客户端的断开请求后,先回复一个确认报文,核心信息:ACK=1(确认收到客户端的FIN请求),ack=u+1(表示“我已经收到你所有的数据,你可以放心”),seq=v(服务器当前的序列号)。

目的:告诉客户端“我收到你要断开的请求了,但我这边可能还有数据没发送完,你先等一等,我发完数据就跟你断开”。

注意这一步只是确认“收到断开请求”,不是真正断开连接,服务器此时还可能在向客户端发送剩余数据。

此时,客户端状态:FIN-WAIT-2(终止等待2,等待服务器发送自己的断开请求);服务器状态:CLOSE-WAIT(关闭等待,正在发送剩余数据)。

第三步:服务器 → 客户端(FIN=1,ACK=1,seq=w,ack=u+1)

服务器发送完所有剩余数据后,向客户端发送断开连接请求报文,核心信息:FIN=1(表示服务器也没有数据要发送了,准备断开连接),ACK=1(再次确认),seq=w(服务器最后一次发送数据的序列号+1),ack=u+1(和第二步的ack一致,再次确认收到客户端所有数据)。

目的:告诉客户端“我这边也没有数据要发送了,我们可以正式断开连接了”。

此时,服务器状态:LAST-ACK(最后确认,等待客户端的最终确认)。

第四步:客户端 → 服务器(ACK=1,seq=u+1,ack=w+1)

客户端收到服务器的FIN请求后,回复一个最终确认报文,核心信息:ACK=1(确认收到服务器的FIN请求),ack=w+1(表示“我收到你所有的数据了,你可以放心断开”),seq=u+1(客户端当前的序列号)。

目的:告诉服务器“我已经收到你要断开的请求,所有数据都已接收完毕,我们可以彻底断开连接了”。

此时,客户端状态:TIME-WAIT(时间等待,等待2MSL后彻底关闭);服务器收到该报文后,状态变为CLOSED(已关闭)。

补充:客户端的TIME-WAIT状态(等待2倍的最大报文段寿命),是为了确保服务器能收到客户端的最终确认——如果服务器没收到,会重发FIN请求,客户端在TIME-WAIT期间能再次回复,避免服务器一直等待。

为什么是四次挥手,不是三次?

核心原因:服务器收到客户端的FIN请求后,可能还有未发送完的数据,无法立即发送FIN请求,需要先回复ACK确认,等数据发送完毕后,再发送FIN请求,因此需要分两步,无法和ACK合并

简单说:三次握手时,服务器的SYN和ACK可以合并发送(第二步),因为服务器不需要准备数据,收到请求后可以立即同步;但四次挥手时,服务器收到FIN后,可能还有数据要处理,只能先确认(ACK),再发送FIN,因此必须分两步,形成四次挥手。

http://www.jsqmd.com/news/536912/

相关文章:

  • 百川2-13B-4bits模型压缩对比:OpenClaw任务场景下的显存与速度权衡
  • linux基础学习三
  • YOLO X Layout实战:从扫描PDF中自动提取标题与表格的Python实现
  • Hunyuan-MT-7B低资源语言支持展示:东南亚小语种(老挝、缅甸、高棉)实测
  • Qwen3.5开源模型实测
  • 智能客服原型:OpenClaw接入Qwen3.5-9B处理电商常见问答
  • 从零开始:DeepWiki-Open 开源AI维基生成器完全部署指南
  • Anomalib使用
  • 阿里蚂蚁Kimi连夜换引擎!混合注意力炸场,456B模型200万token秒吞,API直接打2折
  • ESLint代码规范(一)
  • SkeyeVSS中国标GB28181、流媒体源RTMP/RTSP/HTTP/ONVIF、RTMP推流等协议视频流实时播放流程详解
  • ButtonIn:嵌入式C++轻量级按键消抖库设计与实践
  • OpenClaw进阶调试:Qwen3.5-4B-Claude任务失败原因分析
  • leetcode-hot100-10回溯
  • OpenClaw内存优化:让nanobot镜像在4GB设备上流畅运行
  • C语言变量与函数命名规范详解
  • 树莓派X96 一、智能小车初框架(无视觉)
  • SDMatte Web化服务运维指南:supervisorctl管理与日志定位技巧
  • AI教材写作指南:低查重秘诀,快速生成专业教材不是梦!
  • 济南华泰精工:负压出料/高温齿轮泵/高粘度齿轮泵/高精度计量泵/不锈钢泵/分子蒸馏泵/同步分流马达/数字同步马达/选择指南 - 优质品牌商家
  • 51单片机非接触红外测温
  • KAIST团队突破3D游戏世界生成极限:让AI真正理解你的每一个操作
  • 基于CANopen协议的关节电机位置控制方法与实例
  • 像素幻梦创意工坊效果展示:支持透明通道(Alpha)的像素图生成与导出
  • 微信小程序组件事件冒泡问题排查与解决方案
  • VUE.JS 实践 第三章
  • 揭秘AI专著生成秘诀!掌握这些工具,轻松打造专业学术专著
  • SQL 中聚集函数(Aggregate Functions)与 `ANY`/`ALL` 谓词的核心用法、语义等价关系及实际应用要点
  • 在 SAP 中,Cost Object(成本对象) 是归集、控制与结算成本的核心载体,其设置与定义分为主数据创建(前台操作)和后台配置(SPRO)两大场景,不同类型成本对象路径不同
  • Java中的继承:从入门到精通