Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题( 四 )
本文插图
第二个报文 —— SYN + ACK 报文
- 服务端收到客户端的 SYN 报文后 , 首先服务端也随机初始化自己的序号(server_isn) , 将此序号填入 TCP 首部的「序号」字段中 , 其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1 。 最后把该报文发给客户端 , 该报文也不包含应用层数据 , 之后服务端处于 SYN-RCVD 状态 。
本文插图
第三个报文 —— ACK 报文
- 客户端收到服务端报文后 , 还要向服务端回应最后一个应答报文 , 首先该应答报文 TCP 首部 ACK 标志位置为 1, 其次「确认应答号」字段填入 server_isn + 1, 最后把报文发送给服务端 , 这次报文可以携带客户到服务器的数据 , 之后客户端处于 ESTABLISHED 状态 。
- 服务器收到客户端的应答报文后 , 也进入 ESTABLISHED 状态 。
一旦完成三次握手 , 双方都处于 ESTABLISHED 状态 , 此致连接就已建立完成 , 客户端和服务端就可以相互发送数据了 。
如何在 Linux 系统中查看 TCP 状态?
TCP 的连接状态查看 , 在 Linux 可以通过 netstat -napt 命令查看 。
本文插图
TCP 连接状态查看
为什么是三次握手?不是两次、四次?
相信大家比较常回答的是:“因为三次握手才能保证双方具有接收和发送的能力 。 ”
这回答是没问题 , 但这回答是片面的 , 并没有说出主要的原因 。
在前面我们知道了什么是 TCP 连接:
- 用于保证可靠性和流量控制维护的某些状态信息 , 这些信息的组合 , 包括Socket、序列号和窗口大小称为连接 。
接下来以三个方面分析三次握手的原因:
- 三次握手才可以阻止历史重复连接的初始化(主要原因)
- 三次握手才可以同步双方的初始序列号
- 三次握手才可以避免资源浪费
我们来看看 RFC 793 指出的 TCP 连接使用三次握手的首要原因:
The principle reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.
简单来说 , 三次握手的首要原因是为了防止旧的重复连接初始化造成混乱 。
网络环境是错综复杂的 , 往往并不是如我们期望的一样 , 先发送的数据包 , 就先到达目标主机 , 反而它很骚 , 可能会由于网络拥堵等乱七八糟的原因 , 会使得旧的数据包 , 先到达目标主机 , 那么这种情况下 TCP 三次握手是如何避免的呢?
本文插图
三次握手避免历史连接
客户端连续发送多次 SYN 建立连接的报文 , 在网络拥堵等情况下:
- 一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端;
- 那么此时服务端就会回一个 SYN + ACK 报文给客户端;
- 客户端收到后可以根据自身的上下文 , 判断这是一个历史连接(序列号过期或超时) , 那么客户端就会发送 RST 报文给服务端 , 表示中止这一次连接 。
推荐阅读
- 『Java』java数据结构系列——什么是数据结构
- 『Java』马云:成功人跟普通人差不多,但这三点我一定要分享给所有年轻人
- 小谢娱乐哦引来广大网友狂点赞,直呼炸天,程序员用Java实现扫雷小游戏
- 「客户端」学习网络编程,不了解TCP协议?难怪面试被刷下去,还不来学习!
- 体坛焦点全场吊打对手,上港苦主独造三球,4-0狂胜!申花亚冠劲敌踢疯了
- #Java#java线程到底有多少种状态?
- 【皇室战争】皇室战争:狂暴模式被吊打?学会这套卡组,轻松连胜拿奖励
- Muster电竞单挑省级马超惨遭吊打,网友:真香,国服瑶妹打脸梦泪失败
- 星空游戏精选小羊火龙溢出严重,法师吊打满配物理队?明日方舟高台输出太强
- #智能手表#1、初识java-1
