做网站的eclip,加盟网站制作运营,小程序开发费用明细怎么填,软件商店下载安装免费✏️作者#xff1a;银河罐头 #x1f4cb;系列专栏#xff1a;JavaEE #x1f332;“种一棵树最好的时间是十年前#xff0c;其次是现在” 目录TCP 建立连接(三次握手)为啥不能是 4 次#xff1f;为啥不能是 2 次#xff1f;三次握手的意义#xff1a;TCP 断开连接(四… ✏️作者银河罐头 系列专栏JavaEE “种一棵树最好的时间是十年前其次是现在” 目录TCP 建立连接(三次握手)为啥不能是 4 次为啥不能是 2 次三次握手的意义TCP 断开连接(四次挥手)为啥是 4 次1.CLOSE_WAIT2.TIME_WAITTCP 的建立连接过程(三次握手)和断开连接过程(四次挥手)
TCP 建立连接(三次握手)
通信双方各自要记录对方的信息彼此之间要相互认同。 举个栗子 这个过程中的每次通信都称为是一次握手(形象的比喻)
上面的例子中进行了4 次交互但是其中有 2 次可以合并成 1 次。 总结所谓的三次握手本质上是四次交互。通信双方各自向对方发起一个建立连接的请求然后再各自向对方回应一个 ack。这里其实是有 4 次信息交互但是其中有 2 次交互是可以合并成 1 次交互的。因此就构成了三次握手。
为啥不能是 4 次
为啥要把中间这 2 次合并不合并行嘛
必须合并
封装分用 2 次一定比封装分用 1 次成本更高。 举个栗子 我想在淘宝上买 3 样东西 假设我是在一个淘宝店铺下单的通过多个订单来买的此时店家是通过 3 个快递发给我还是 1 个快递直接发了分 3 次发3 次包装成本3 次快递费1 次发了1 次快递成本1 次快递费。 为啥不能是 2 次
如果是 2 次握手能否完成建立连接的过程
不行(无法完全验证双方的发送和接收能力)
除了通信双方要彼此认同之外三次握手还有别的作用。
三次握手另外一个重要作用验证通信双方各自的发送能力和接收能力是否正常。
三次握手也是一定程度的保证了 TCP 传输的可靠性。(起的是辅助作用) 举个例子 张三和李四打游戏开黑需要连麦 第一次交互 当李四听到听得到嘛, 李四就知道了 1.张三的麦克风 ok 2.李四的耳机 ok 张三知道了 (空) 第二次交互 当张三听到能听到, 张三就知道了 1.张三的耳机 ok 2.李四的麦克风 ok 建立在第一次通信的基础上 3.张三的麦克风 ok 4.李四的耳机 ok 第三次交互 李四听到好了 意味着第二次通信李四说的能听到张三已经接收了 李四就知道了: 1.李四的麦克风 ok 2.张三的耳机 ok 此时双方都知道了彼此的麦克风和耳机都是 ok 的 连接包含连接的建立断开和维护三次握手只是建立这个环节。 “有连接” 1.需要连接先建立好才能进行通信 2.如果连接断开了此时就无法进行通信了。 3.连接建立过程中通信双方要保存好对方的信息。 有没有连接和是否确认应答 没有任何关系。 确认应答体现的是可靠传输可靠传输和有连接是不相关的。 无连接也可以可靠传输。eg飞书/钉钉/企业微信发个消息不需要建立连接直接就能发发个消息有个已读状态这就相当于 ack 三次握手的意义
1.让通信双方各自建立对对方的认同。
2.验证通信双方各自的发送能力和接收能力是否 ok.
3.在握手的过程中双方来协调一些重要的参数。(比如 TCP 的序号不一定是从 1 开始编号的双方协商从哪个数字开始编号)
TCP 通信过程中有些数据通信双方要相互同步此时就需要有这样的交互过程恰好可以利用三次握手的机会来完成数据的同步。 客户端主动给服务器发起建立连接请求称为syn同步报文段
建立连接阶段主要认识 2 个状态
1.LISTEN 服务器的状态
表示服务器已经准备就绪随时可以有客户端来建立连接。(相当于手机开机信号良好随时可以有人来打电话)
2.ESTABLISHED 客户端和服务器都有的状态
连接建立完成接下来可以进行通信了。(相当于电话打过去对方接通了)
TCP 断开连接(四次挥手)
挥手和握手都是客户端服务器之间的数据交互。
四次挥手和三次握手非常类似。通信双方给对方发起断开连接请求然后再各自给对方一个回应。 为啥是 4 次
在断开连接过程中中间两次通常情况下不能合并(特殊情况下可以)
两个数据发送的时机相同才能合并不同就不能合并。 举个栗子 我要在淘宝上买 3 样东西。 从同一个店铺买。 如果这 3 个订单是同一时间下的此时就可以一个包裹发过来 如果是分开下的呢 如果是今天买了 A过了一周买了 B再过一个月买了 C。此时就只能分成多个包裹发货了。 三次握手的中间 2 次能够合并是因为他俩是同一时机。具体来说三次握手 这 3 次交互过程是纯内核完成的(应用程序感知不到也干预不了)
服务器的系统内核收到 syn 之后就会立即发送 ack 也会立即发送 syn FIN 的发起不是由内核控制的而是由应用程序调用 socket 的 close 方法(或者进程退出)才会触发 FIN。
ACK 是由内核控制的是收到 FIN 之后立即返回 ACK
所以第 2 步的 ACK 和第 3 步的 FIN 这两者之间就会隔了一个时间差这个时间是长是短得看具体代码的实现。 之前写过的 TcpEchoServer 代码 四次挥手中涉及到的 2 个重要的 TCP 状态
1.CLOSE_WAIT
出现在被动发起断开连接的一方。
建立连接一定是客户端主动发起请求而断开连接有可能是客户端主动发起也可能是服务器主动发起。 举个栗子 谈恋爱追人的时候一般是男生主动。但是分手的时候可以是男生提分手也可以是女生提分手 等待关闭(等待调用 close 方法关闭 socket)
收到 FIN 并立即返回 ACK 之后状态就设置成 CLOSE_WAIT下一步就应该轮到应用程序调用 close 完成后续的 2 次挥手。
2.TIME_WAIT
出现在主动断开连接的一方。
假设是客户端主动断开连接当客户端收到 第 3 次 FIN 并 返回第 4 次 ACK 之后 TCP 就进入 TIME_WAIT 状态。
此时相当于 4 次挥手都挥完了。
此时这里的 TIME_WAIT 要保持 当前的 TCP 连接状态不要立刻就释放。
为啥不要立即释放为啥要以 TIME_WAIT 保留一会儿连接
最后这个 ACK 才刚发出去对方还没有收到呢万一丢包了呢。
在三次握手和四次挥手的过程中也是同样存在超时重传的。
如果最后一个 ACK 丢包了站在服务器的视角来看服务器不知道是因为 ACK 丢了还是自己发的 FIN 丢了所以统一视为 FIN 丢了统一进行重传操作。
既然服务器可能会重传 FIN客户端就需要针对这个重传的 FIN 进行 ACK 响应。如果刚才把连接彻底释放了这样的话 ACK 就没办法进行了。
因此使用 TIME_WAIT 状态保留一段时间就是为了能够处理最后一个 ACK 丢包的情况能够在收到重传的 FIN 进行 ACK 响应。
TIME_WAIT 会等如果等了一段时间也没有收到这个重传的 FIN此时就认为 最后一个 ACK 没丢此时就彻底断开连接了。
TIME_WAIT 具体保持多长时间就真正释放呢
约定一个时间2 MSL
MSL 指的是互联网上两个结点之间数据传输消耗的最大时间。
MSL 具体是几
通常情况下这个值是 60 s
MSL 相当于是一个经验值。按照一般的经验来说绝大部分数据报传输的时间都不会超过 MSL
如果经历了 2 MSL 还没有收到重传的 FIN此时就认为最后一个 ACK 成功到达了(认为对方没有重传 FIN) 是每个状态都等 2 MSL 吗
TIME_WAIT 才是等这个时间其他的交互过程都是跟着超时重传的时间阈值走的