TCP连接断开原理剖析
TCP连接三次握手
TCP协议在双方建立连接的时候需要三次握手, 所谓的三次握手即TCP连接的建立。这个连接必须是一方主动打开,另一方被动打开的。以下为客户端主动发起连接的图解:
其中比较重要的字段有:
SYN(synchronous建立连接) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束)
RST(reset重置) URG(urgent紧急)
tips
不要将确认序号Ack与标志位中的ACK搞混了。确认方Ack=发起方Seq+1,两端配对
为什么要进行第三次握手?
为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
抓包剖析
TCP协议是面向连接的通信协议,即传输数据之前,在客户端和服务端需要建立逻辑连接,然后再传输数据。
客户端与服务端在进行连接建立的时候,需要经过三个步骤,这个3个步骤相当于3次握手。
- 客户端到服务端: 我要连接
- 服务端到客户端: 好的,已经连接上了
- 客户端到服务端: 收到,确认已连接上了
我们可以借助于一个工具wireshark来抓取TCP客户端与服务端建立连接时数据传输的过程。
客户端代码:
// 创建Socket对象
Socket socket = new Socket("127.0.0.1", 8080);
// 让线程休眠60s
TimeUnit.SECONDS.sleep(60);
服务端代码
// 创建ServerSocket对象
ServerSocket serverSocket = new ServerSocket(9999) ;
// 让线程休眠60s
TimeUnit.SECONDS.sleep(60);
首先运行服务端,然后在运行客户端,在wireshark工具中捕获完整的通信过程,结果如下图所示:
ip.src == 127.0.0.1 and tcp.port==8080
在第一次"握手"时,客户端向服务端发送SYN标志位,目的是与服务端建立连接。Seq代表sequence number(发送数据流序号), 例如:Seq的值是5,说明在数据流中曾经一共发送了 1, 2, 3,4 这4次数据。而在本次"握手"中, Seq的值是0,代表客户端曾经没有给服务端发送数据。另外Len=0也可以看出来是没有数据可供发送的,客户端仅仅发送一个SYN标志位到服端代表要进行连接。
第二次"握手"时,服务端向客户端发送 SYN ACK 标志位,其中ACK标志位表示是对收到的数据包的确认,说明服务端接收到了客户端的连接。ACK的值是1,表示服务端期待下一次从客户端发送数据流的序列号是1,而Seq=0代表服务端曾经并没有给客户端发送数据,而本次也没有发送数据,因为Len=0也证
明了这一点。
第三次“握手”时,客户端向服务端发送的ACK标志位为1, Seq的值是1。Seq=l代表这正是服务端所期望的Ack=1。Len=0说明客户端这次还是没有向服务端传递数据,而客户端向服务端发送ACK 标志位为1的信息,说明客户端期待服务端下一次传送的Seq的值是1。
个人记忆技巧:
其实可以看成客户端和服务器确认双方接受和发送都没问题的过程
1、客户端第一次握手到服务端,服务端知道客户端发送没问题,服务端也知道自己接受没问题,但客户端还不知道自己的发送有没有问题,因此有了二次
2、服务端第二次握手到客户端,此时客户端知道自己发送没问题了,也知道服务端发送没问题,同时也知道自己接受也没问题,但服务端还不知道自己的发送有没有问题。因此有了三次
3、客户端第三次握手到服务端,服务端知道自己的发送也没问题了,可以传输数据了
TCP的四次挥手
所谓的四次挥手即TCP连接的释放(解除)。连接的释放必须是一方主动释放,另一方被动释放。以下为客户端主动发起释放连接的图解:
其中比较重要的字段有:
SYN(synchronous建立连接) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束)
RST(reset重置) URG(urgent紧急)
为什么客户端在TIME-WAIT阶段要等2MSL?
MSL指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长
抓包剖析
客户端与服务端在断开连接的时候需要进行4次"挥手",4次"挥手"的过程如下:
- 客户端到服务端:我关了
- 服务端到客户端:好的,收到
- 服务端到客户端:我也关了
- 客户端到服务端:好的,收到
我们也可以借助于wireshark这个抓包工具来抓取连接断开的整个数据传输的过程。
ip.src == 127.0.0.1 and tcp.port==8080
客户端代码
// 创建Socket对象
Socket socket = new Socket("127.0.0.1", 8080);
// 线程休眠
TimeUnit.SECONDS.sleep(10);
// 关闭连接
socket.close();
服务端代码
// 创建ServerSocket对象
ServerSocket serverSocket = new ServerSocket(8080);
// 获取连接对象
Socket socket = serverSocket.accept();
// 线程休眠
TimeUnit.SECONDS.sleep(10);
// 释放资源
socket.close();
serverSocket.close();
首先运行服务端,然后在运行客户端,在wireshark工具中捕获完整的通信过程,结果如下图所示:
在第一次"挥手"时,客户端到服务器发送标志位FIN ACK,告知服务端客户端关闭了。Seq=1表示本次数据流的序号为1,Ack=1表示客户端期望服务端下一次发送的数据流的序号为1。len=0,说明没有数据传输到服务端。
在第二次"挥手"时,服务端向客户端发送标志位ACK,Seq=1代表的正是客户端想看的Ack=1。Ack=2表示服务端期望下一次客户端发送的数据流的序号为2。len=0,说明没有数据传输到客户端。
在第三次"挥手"时,服务端向客户端发送标志位FIN ACK,告知客户端服务端关闭了。Seq=1代表的正是客
户端想看的Ack=1。Ack=2表示服务端期望下一次客户端发送的数据流的序号为2。len=0,说明没有数据传输到客户端。
在第四次"挥手"时,客户端向服务端发送标志位ACK,告知服务端客户端已经收到服务端关闭信息。Seq=2代表的正是服务端想看的Ack=2,ACK=2表示客户端期望下一次服务端发送的数据流的序号为2。
个人记忆技巧
可以看成是一个打电话的过程
1、客户端告诉服务端我要挂了
2、服务端说好的,我把要你的事情都办好和你说,你在挂
3、服务端说,办好了,你可以挂了,那我也挂了哈
4、客户端说,好的,挂了吧
TCP连接断开原理剖析相关推荐
- 【Java 网络编程】TCP 连接 断开 机制 ( 三次握手 | 四次挥手 )
文章目录 I TCP 连接建立流程 ( 三次握手 ) II SYN 和 ACK 中的随机值 III TCP 连接建关闭流程 ( 四次挥手 ) IV TCP 连接断开的保证 V 四次挥手的必要性 I T ...
- go 监测tcp 连接断开_优化ngrok的tcp连接
ngrok支持tcp tunnel和http以及https,但是ngrok的tcp代理似乎优化不够好,当一段时间闲置tcp连接的话,再连接会出现连接不上的问题. 首先来看看ngrok的tcp tunn ...
- go 监测tcp 连接断开_TCP三次握手和四次挥手以及11种状态
三次握手 置位概念:根据TCP的包头字段,存在3个重要的标识ACK.SYN.FIN ACK:表示验证字段 SYN:位数置1,表示建立TCP连接 FIN:位数置1,表示断开TCP连接 三次握手过程说明: ...
- 【TCP专题】TCP连接断开
当TCP的连接建立完成后,我们就可以尽情的通过TCP连接所创立的会话来进行数据的传输了.当然,再有意思的话题也有说完的时候,所以,当数据传输完之后,TCP该如何善后呢? TCP的四次挥手 TCP的连接 ...
- php实现tcp连接的原理,PHP实现TCP实例
NotifyService.php class NotifyService extends Model { private static $client; private static $redis; ...
- 4个实验,彻底搞懂TCP连接的断开
前言 看到这个标题你可能会说,TCP 连接的建立与断开,这个我熟,不就是三次握手与四次挥手吗?且慢,脑海中可以先尝试回答这几个问题: 四次挥手是谁发起的? 如果断电/断网了连接会断开吗? 什么情况下没 ...
- 协议簇:TCP 解析: 连接断开
简介 接前文 协议簇:TCP 解析: 建立连接, 我们这篇文章来看看 TCP 连接断开的过程,也就是众所周知的"四次挥手"的具体流程. 系列文章 协议簇:TCP 解析:基础 协议簇 ...
- 一个解除TCP连接的TIME_WAIT状态限制的简便方法
近日无意间发现了一个小窍门:当TCP连接所对应socket的接收队列中仍有未读数据时,将此socket强行close后,将使此socket连接不会进入TIME_WAIT状态,用"netsta ...
- java socket 自动重连_socket 如何判断远端服务器的连接状态?连接断开,需重连...
fluent-logger-java is a Java library, to record events via Fluentd, from Java application. https://g ...
最新文章
- 关注中国的房地产市场
- matlab肌电信号平滑滤波_BCIduino 滤波和频谱计算操作
- 【LeetCode-面试算法经典-Java实现】【015-3 Sum(三个数的和)】
- laravel 同数据表字段比较查询和状态不正规排序
- 三轴联动c语言算法,(数控加工)虚拟轴数控机床的仿三轴控制.pdf
- Codeforces Round #208 (Div. 2)D. Dima and Hares
- leetcode-139-单词拆分
- C# 中如何一次 catch 多个异常?
- [牛客] Tree-换根dp(预防加法取模导致等0)
- 主要矛盾和次要矛盾_次要GC,主要GC与完整GC
- zabbix入门之添加主机
- Docker 系列之 常用镜像
- selenium3 + python - js处理readonly属性
- ES6、ES7、ES8、ES9、ES10 新特性ECMAScript版本简介
- win7桌面小工具 html5,Win7桌面小工具打不开怎么办
- 二元函数可微与可导的关系_二元函数的连续偏导数可微之间的关系
- 金融反欺诈常用特征处理方法
- “pcl_isfinite”: 找不到标识符
- java获取一天的开始时间和结束时间
- 数据库增量同步/ETL工具