三次握手,四次挥手,为什么是三次握手四次挥手

三次握手,四次挥手,为什么是三次握手四次挥手三次握手 四次挥手 为什么是三次握手四次挥手四次挥手 TCP 的连接的拆除需要发送四个包 因此称为四次挥手 客户端或服务器均可主动发起挥手动作 由于 TCP 连接时全双工的 因此每个方向都必须单独进行关闭 这个原则是当一方完成他的数据发送任务后就能发送一个 FIN 来终止这个方向的连接 收到一个 FIN 只意味着这一方向上没有数据流动 一个 TCP 连接在收到一个 FIN 后仍能发送数据 首先进行关闭的一方将执行主动关闭 而另一方执行被动关闭 这是因为服务端的 LISTEN 状态下的 socket 当收到

三次握手

图片

图片

两次握手(情况1)

图片

两次握手(情况2)

图片

图片

OK,下面正经地来回答下这个问题,要搞清楚这个问题,首先得了解TCP究竟是如何保证可靠传输的。

图片

PS:TCP协议中,主动发起请求的一端称为『客户端』,被动连接的一端称为『服务端』。不管是客户端还是服务端,TCP连接建立完后都能发送和接收数据。

起初,服务器和客户端都为CLOSED状态。在通信开始前,双方都得创建各自的传输控制块(TCB)。服务器创建完TCB后遍进入LISTEN状态,此时准备接收客户端发来的连接请求。

第一次握手

客户端向服务端发送连接请求报文段。该报文段的头部中SYN=1,ACK=0,seq=x。请求发送后,客户端便进入SYN-SENT状态。

  • PS1:SYN=1,ACK=0表示该报文段为连接请求报文。
  • PS2:x为本次TCP通信的字节流的初始序号。TCP规定:SYN=1的报文段不能有数据部分,但要消耗掉一个序号。

第二次握手

服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1,ACK=1,seq=y,ack=x+1。该应答发送完成后便进入SYN-RCVD状态。

  • PS1:SYN=1,ACK=1表示该报文段为连接同意的应答报文。
  • PS2:seq=y表示服务端作为发送者时,发送字节流的初始序号。
  • PS3:ack=x+1表示服务端希望下一个数据报发送序号从x+1开始的字节。

第三次握手

当客户端收到连接同意的应答后,还要向服务端发送一个确认报文段,表示:服务端发来的连接同意应答已经成功收到。该报文段的头部为:ACK=1,seq=x+1,ack=y+1。客户端发完这个报文段后便进入ESTABLISHED状态,服务端收到这个应答后也进入ESTABLISHED状态,此时连接的建立完成!

为什么连接建立需要三次握手,而不是两次握手?

防止失效的连接请求报文段被服务端接收,从而产生错误。

PS:失效的连接请求:若客户端向服务端发送的连接请求丢失,客户端等待应答超时后就会再次发送连接请求,此时,上一个连接请求就是『失效的』。

若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源。

TCP四次挥手

图片

TCP连接的释放一共需要四步,因此称为『四次挥手』。

我们知道,TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。

第一次挥手

若A认为数据发送完成,则它需要向B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:FIN=1,seq=u。此时,A将进入FIN-WAIT-1状态。

  • PS1:FIN=1表示该报文段是一个连接释放请求。
  • PS2:seq=u,u-1是A向B发送的最后一个字节的序号。

第二次挥手

B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。此时B进入CLOSE-WAIT状态,并向A发送连接释放的应答,其报文头包含:ACK=1,seq=v,ack=u+1。

  • PS1:ACK=1:除TCP连接请求报文段以外,TCP通信过程中所有数据报的ACK都为1,表示应答。
  • PS2:seq=v,v-1是B向A发送的最后一个字节的序号。
  • PS3:ack=u+1表示希望收到从第u+1个字节开始的报文段,并且已经成功接收了前u个字节。

A收到该应答,进入FIN-WAIT-2状态,等待B发送连接释放请求。

第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。

第三次挥手

当B向A发完所有数据后,向A发送连接释放请求,请求头:FIN=1,ACK=1,seq=w,ack=u+1。B便进入LAST-ACK状态。

第四次挥手

A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有B的重发请求的话,就进入CLOSED状态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。

为什么 A 要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED状态

为了保证B能收到A的确认应答。若A发完确认应答后直接进入CLOSED状态,那么如果该应答丢失,B等待超时后就会重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应,因此B永远无法正常关闭。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229845.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午3:45
下一篇 2026年3月16日 下午3:45


相关推荐

  • java问号表达式用法

    java问号表达式用法JAVA 问号 运算符的用法 Java 提供一个特别的三元运算符 ternary 经常用于取代某个类型的 if then else 语句 这个运算符就是 初看起来有点迷惑但是一旦掌握了它 用 运算符是很方便高效的 运算符的通用格式如下 expression1

    2026年3月17日
    3
  • 文心一言怎么用?一分钟教你玩转ERNIE Bot!

    文心一言怎么用?一分钟教你玩转ERNIE Bot!

    2026年3月12日
    2
  • 汇总:国内6款OpenClaw一站式部署与实测

    汇总:国内6款OpenClaw一站式部署与实测

    2026年3月13日
    2
  • sql server 2005卸载教程_sql卸载工具

    sql server 2005卸载教程_sql卸载工具如果您要安装新版的sql就必须先完整的卸载sql2005,如果你按照常规的方法是不能完整的卸载sql2005,从而会引起安装的时候说sql已经挂起的错误,sql2005卸载工具(sqlserver2005卸载工具),是一个帮你完整的清理已经安装的sql的工具。MicrosoftSQLServer2005是一个全面的数据库平台,使用集成的商业智能(BI)工具提供了企业级的数据管理。Mi…

    2025年11月24日
    4
  • 滴滴新算法让你应对女友?道翰天琼认知智能机器人平台API接口大脑为您揭秘-64

    滴滴新算法让你应对女友?道翰天琼认知智能机器人平台API接口大脑为您揭秘-64某个周末晚上,小陈约好了和女朋友去商场吃饭看电影。小陈平时喜爱打游戏,此时正在专心打农药。“啊!ZZ队友送人头,白瞎我最强亚索!伤心~”而小陈的女朋友这个时候打来了电话:你收拾好了吗?我已经到口红啦……小陈内心:“这次竟然这么快?我还以为刚到眉毛呢,可是我还想再开一局逆风翻盘拿五杀呢!但是又不能迟到啊……小陈想到先点开打车软件计算一下双方的时间吧:首先设置好出发地为女朋友家,目的地为要去的商场,呼叫快车,显示要30分钟。再来设置一下自己的出发地,呼叫快车,哇!只要15分钟。小陈于是决定…

    2022年6月2日
    54
  • Python 数组操作_python中数组的表示形式

    Python 数组操作_python中数组的表示形式文章目录前言 一、numpy是什么? 二、使用步骤 1.引入库 2.读入数据 总结前言在python中本身有着列表等数据结构,但是列表只是一种数据的存储容器,不具备任何计算能力。故引入数组的概念。提示:以下是本篇文章正文内容,下面案例可供参考一、numpy是什么?NumPy是一种非常常用的第三方模块,在学习数据分析及挖掘时经常能够用到他。接下来就阐述一些使用numpy进行的基本操作。二、使用步骤1.引入库代码如下(示例):i…

    2022年8月13日
    12

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号