TCP 连接断开

在当今数字化时代,互联网已经成为了人们生活中不可或缺的一部分。而在互联网的基础之上,TCP协议扮演着关键的角色,它负责着数据在网络中的可靠传输。在TCP连接的建立过程中,我们已经了解了三次握手的过程和原理。然而,连接的建立只是TCP协议的一部分,同样重要的是连接的断开过程。本文将重点探讨TCP连接的断开过程,包括四次挥手的过程和状态变迁,以及为什么挥手需要四次和为什么需要TIME_WAIT状态。通过深入理解TCP连接断开的过程,我们可以更好地理解网络通信的原理

TCP 四次挥手过程和状态变迁

TCP断开连接需要通过四次挥手的方式。双方都有能力主动断开连接,一旦断开连接,主机中的各种「资源」将被释放。那么我们将详细讲解下TCP四次挥手的原理及过程!

  • 当客户端打算关闭连接时,它会发送一个TCP首部中FIN标志位被置为1的报文,即FIN报文。随后,客户端进入FIN_WAIT_1状态。
  • 当服务端收到该报文后,会向客户端发送一个ACK应答报文,并进入CLOSED_WAIT状态。
  • 客户端接收到服务端的ACK应答报文后,进入FIN_WAIT_2状态。
  • 服务端等待处理完数据后,也会向客户端发送一个FIN报文,然后进入LAST_ACK状态。
  • 客户端收到服务端的FIN报文后,会回复一个ACK应答报文,并进入TIME_WAIT状态。
  • 一旦服务端收到了ACK应答报文,就进入CLOSE状态,这样服务端就完成了连接的关闭。
  • 客户端经过2MSL一段时间后,自动进入CLOSE状态,这样客户端也完成了连接的关闭。

在TCP连接的断开过程中,我们可以观察到每个方向都需要发送一个FIN报文和接收一个ACK报文,因此通常将这个过程称为四次挥手。

需要注意的一点是,只有主动发起关闭连接的一方,才会进入TIME_WAIT状态。这是因为在关闭连接后,客户端需要等待一段时间(通常为两倍的最大报文段生存时间,也即2MSL)来确保服务端收到了自己的ACK应答报文。这样做的目的是为了防止已经关闭的连接上出现延迟的报文段,确保连接的可靠关闭。而服务端则不需要等待这段时间,因此没有TIME_WAIT状态。

为什么挥手需要四次?

为了更好地理解为什么挥手需要四次,让我们再来回顾一下双方发出FIN包的过程。这样我们就能理解为什么需要四次挥手了。

在关闭连接时,当客户端向服务端发送FIN时,这仅仅表示客户端不再发送数据了,但是它仍然可以接收数据。

当服务端收到客户端的FIN报文时,它首先会回复一个ACK应答报文。然而,服务端可能还有数据需要处理和发送,所以它会等待直到它不再发送数据时,才会发送FIN报文给客户端,表示同意现在关闭连接。

通过上述过程,我们可以看出,服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN通常会分开发送,这就导致了比三次握手多了一次挥手的过程。

为什么 TIME_WAIT 等待的时间是 2MSL?

MSL是Maximum Segment Lifetime,即报文的最大生存时间,它表示报文在网络中存在的最长时间。超过此时间,报文将被丢弃。因为TCP协议是基于IP协议的,IP头部有一个TTL字段,它表示数据报可以经过的最大路由数。每经过一个路由器,TTL值就减1。当TTL值为0时,数据报将被丢弃,并且发送ICMP报文通知源主机。

MSL和TTL的区别在于单位。MSL的单位是时间,而TTL是经过的路由跳数。因此,为了确保报文已经自然消亡,MSL应该大于或等于TTL消耗为0的时间。

TIME_WAIT等待2倍MSL的合理解释是:网络中可能存在来自发送方的数据包。当这些数据包被接收方处理后,它会向对方发送响应,因此往返需要等待2倍的时间。就是确保最后一个ACK被服务端接收到了,如果没有接收到也要给足时间让服务器端的第三次挥手的FIN重新传过来。

举个例子,如果被动关闭方没有收到断开连接的最后一个ACK报文,就会触发超时重发FIN报文。另一方收到FIN报文后,会重发ACK给被动关闭方,这样来回就需要2个MSL的时间。

2MSL时间是从客户端接收到FIN后发送ACK开始计时的。如果在TIME_WAIT时间内,因为客户端的ACK没有传输到服务端,客户端又接收到了服务端重发的FIN报文,那么2MSL时间将重新计时。

在Linux系统中,默认的2MSL时间是60秒,即一个MSL为30秒。Linux系统停留在TIME_WAIT状态的时间是固定的60秒。

在Linux内核代码中,它的定义名为TCP_TIMEWAIT_LEN:

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
state, about 60 seconds */

如果要修改TIME_WAIT的时间长度,只能修改Linux内核代码中TCP_TIMEWAIT_LEN的值,并重新编译Linux内核。

为什么需要 TIME_WAIT 状态?

TIME_WAIT 状态的存在是为了确保网络连接的可靠关闭。只有主动发起关闭连接的一方(即主动关闭方)才会有 TIME_WAIT 状态。

TIME_WAIT 状态的需求主要有两个原因:

  • 防止具有相同「四元组」的「旧」数据包被收到:在网络通信中,每个 TCP 连接都由源 IP 地址、源端口号、目标 IP 地址和目标端口号这四个元素唯一标识,称为「四元组」。当一方主动关闭连接后,进入 TIME_WAIT 状态,它仍然可以接收到一段时间内来自对方的延迟数据包。这是因为网络中可能存在被延迟传输的数据包,如果没有 TIME_WAIT 状态的存在,这些延迟数据包可能会被错误地传递给新的连接,导致数据混乱。通过保持 TIME_WAIT 状态,可以防止旧的数据包干扰新的连接。
  • 保证「被动关闭连接」的一方能被正确关闭:当连接的被动关闭方接收到主动关闭方的 FIN 报文(表示关闭连接),它需要发送一个确认 ACK 报文给主动关闭方,以完成连接的关闭。然而,网络是不可靠的,ACK 报文可能会在传输过程中丢失。如果主动关闭方在收到 ACK 报文之前就关闭连接,被动关闭方将无法正常完成连接的关闭。TIME_WAIT 状态的存在确保了被动关闭方能够接收到最后的 ACK 报文,从而帮助其正常关闭连接。

防止旧连接的数据包

假设TIME-WAIT状态没有适当的等待时间或时间过短,延迟的数据包抵达后可能会引发严重的问题。

例如,服务端在关闭连接之前发送的SEQ = 301报文被网络延迟了。然后,同一端口的TCP连接被复用,并且延迟的SEQ = 301到达了客户端。在这种情况下,客户端有可能正常地接收到这个过期的报文,从而导致数据错乱等严重问题的发生。

为了解决这个问题,TCP设计了一个机制,即经过2MSL的时间,足够让连接中的两个方向上的数据包都被丢弃。这样,原来连接的数据包在网络中自然消失,再出现的数据包一定是由新建立的连接产生的,从而避免了数据错乱等问题的发生。

保证连接正确关闭

TIME-WAIT状态的作用是等待足够的时间,以确保最后的ACK报文能够被被动关闭方接收,并帮助其正常关闭。

假设TIME-WAIT没有适当的等待时间或时间过短,断开连接可能会导致以下问题:

例如,如果在四次挥手的过程中,客户端发送的最后一个ACK报文在网络中丢失,并且客户端的TIME-WAIT状态过短或没有设置,则客户端会直接进入CLOSE状态,而服务端则会一直处于LAST-ACK状态。这种情况下,连接无法正常关闭。

另外,当客户端发起建立连接的SYN请求后,如果服务端发送的RST报文给客户端,连接建立的过程将会被终止。

如果TIME-WAIT等待的时间足够长,会发生以下两种情况:

  • 服务端正常接收到四次挥手的最后一个ACK报文,从而正常关闭连接。
  • 服务端没有收到四次挥手的最后一个ACK报文时,会重发FIN关闭连接报文并等待新的ACK报文。

因此,客户端在TIME-WAIT状态等待2MSL时间后,可以确保双方的连接都能够正常关闭。

这里再科普一下有关知识,大多数三次握手和四次挥手都没有提到。为什么第三次挥手的时候会发送ack呢?不是正常就是发送fin就可以了吗?

在TCP协议中,除了初始连接的第一个SYN包,其中ACK字段被设置为0,而其他所有的TCP包都会将ACK字段设置为1。这个ACK字段的作用是用来确认接收方已经成功接收到数据。如果有数据需要发送,TCP协议会在发送数据的同时附带ACK来确认对方的数据。如果数据在传输过程中丢失,TCP会进行数据重传。ACK字段是TCP头部必备的,这32个位空着也是空着,那么干脆让除了初始报文段之外的所有报文段的ACK字段都有效。

总结

TCP连接的断开需要通过四次挥手的过程来完成。双方都有能力主动断开连接,并且在断开连接后,各种资源将被释放。四次挥手的过程涉及到双方发送FIN和ACK报文的交互,确保数据的可靠传输和连接的正确关闭。其中,主动关闭方会进入TIME_WAIT状态,等待一段时间来确保对方已经接收到最后的ACK报文。TIME_WAIT状态的存在是为了防止旧连接的数据包干扰新连接,并确保被动关闭方能够正常关闭连接。挥手需要四次的原因是为了确保数据的完整传输和连接的可靠关闭。TIME_WAIT状态等待2倍MSL的时间是为了确保网络中的数据包都已经消失。

解密TCP连接断开:四次挥手的奥秘和数据传输的安全的更多相关文章

  1. TCP建立连接的三次握手和TCP连接断开的四次挥手

    1. TCP建立连接的3次握手 2. TCP断开连接的四次挥手 [注意]中断连接端可以是Client端,也可以是Server端. 图3—Client端主动发起关闭连接请求 1. 假设Client端主动 ...

  2. TCP断开连接(四次挥手)

    四次挥手 ACK建立连接之后都为1. 1.A发送释放连接报文段,FIN=1. 2.B收到并回复确认,TCP进入半关闭状态,即此时B能向A发送,但是A无法向B发送数据. 3.当B传输完所有数据之后,发送 ...

  3. TCP释放连接的四次挥手过程

    TCP断开连接的过程:TCP四次挥手. 数据传输结束后,通信的双方都可释放连接.现在A和B都处于ESTABLISHED状态.A的应用进程先向TCP发出连接释放报文段,主动关闭TCP连接.A把连接释放报 ...

  4. 为什么建立TCP连接需要三次握手,为什么断开TCP连接需要四次握手,TIME_WAIT状态的意义

    为什么建立TCP连接需要三次握手? 原因:为了应对网络中存在的延迟的重复数组的问题 例子: 假设client发起连接的连接请求报文段在网络中没有丢失,而是在某个网络节点长时间滞留了,导致延迟到达ser ...

  5. 利用tcpdump抓包工具监控TCP连接的三次握手和断开连接的四次挥手

    TCP传输控制协议是面向连接的可靠的传输层协议,在进行数据传输之前,需要在传输数据的两端(客户端和服务器端)创建一个连接,这个连接由一对插口地址唯一标识,即是在IP报文首部的源IP地址.目的IP地址, ...

  6. 通俗易懂地讲解TCP建立连接的三次握手和释放连接的四次挥手

    TCP建立连接时,为什么要进行三次挥手? 每一次TCP连接都需要三个阶段:连接建立.数据传送和连接释放.三次握手就发生在连接建立阶段. 在谢希仁著<计算机网络>第四版中讲三次握手的目的是为 ...

  7. TCP三次握手(建立连接)/四次挥手(关闭连接)

    TCP数据包格式 顺序号(32位):用来标识从TCP源端向TCP目的端发送的数据字节流,它表示在这个报文段中的第一个数据字节的顺序号.如果将字节流看作在两个应用程序间的单向流动,则TCP用顺序号对每个 ...

  8. TCP三次握手和断开四次挥手

    TCP三次握手 1主机A发送消息请求与主机B连接 2主机B回复消息同意与主机A连接 3主机A确认主机B的同意连接,并建立连接 TCP的四次挥手 1客户端发送FIN到服务器,请求关闭与服务器的连接(意思 ...

  9. TCP建立连接的三次握手和释放连接的四次挥手

    TCP建立连接时,为什么要进行三次握手? 举个打电话的例子: A : 你好我是A,你听得到我在说话吗 B : 听到了,我是B,你听到我在说话吗 A : 嗯,听到了 建立连接,开始聊天! 第一次握手 第 ...

  10. 网络编程---scoket使用,七层协议,三次挥手建连接,四次挥手断连接

    目录 == 网络编程 == 软件开发架构 网络编程 互联网协议 TCP协议的工作原理 Socket == 网络编程 == 软件开发架构 开发软件 必须要开发一套 客户端与服务端 客户端与服务端的作用 ...

随机推荐

  1. 如何判断Keil MDK ARM中已经破解?如何判断Keil MDK ARM中已经安装了相应的器件库?如何判断CubeMX的器件库已经安装成功?

    如何判断CubeMX的器件库已经安装成功?请对照下图 如何判断Keil MDK ARM中已经安装了相应的器件库?请看下图 如何判断CubeMX的器件库已经安装成功?请对照下图

  2. 用python SMTP发送简单邮件

    python SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议 它是一组由源地址到目的地址传送邮件得规则,由它来控制信件的中转方式. Pyth ...

  3. 用AI技术实现自动化的社交媒体广告投放,提高广告效果和收益

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 随着社交媒体的普及,广告投放已经成为了广告行业的重要一环.在过去的几年中,社交媒体广告投放的效果和收益都得到了显著提高,但同时也存在着一些 ...

  4. Kafka 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

    如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性? >幂等性,通俗点说,就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错. kafka 的机制:  K ...

  5. 固定型思维 VS 成长型思维

    回顾进入职场工作以来,对比曾经的学生时代,如果让我讲一个对自己影响最大的改变,那就是思维模式的一个转变. 具体来说,就是从一个典型的固定型思维转变成一个具备有成长型思维的人. 当然,我不敢妄称自己已经 ...

  6. fidder中勾选check for certificate revocations导致手机无法连上fidder服务器

    在测试过程中因为要获取一个小程序登录API,就用手机设置代理后抓取,在抓取过程中发现提示用户名密码错误(未使用代理正常登录) 遂逐步查找,在与别人核对tools-option发现自己https页签中勾 ...

  7. Open LLM 排行榜近况

    Open LLM 排行榜是 Hugging Face 设立的一个用于评测开放大语言模型的公开榜单.最近,随着 Falcon 的发布并在 Open LLM 排行榜 上疯狂屠榜,围绕这个榜单在推特上掀起了 ...

  8. CF103B Cthulhu题解

    CF103B Cthulhu 点击查看题目 点击查看思路 如果 \(n < m\),那么会形成多个环. 如果 \(n > m\),那么不会形成环. 只有 \(n = m\) 时会形成环, ...

  9. 求任意两个正整数的最大公约数(GCD)。

    问题描述 求任意两个正整数的最大公约数(GCD). 问题分析 如果有一个自然数a能被自然数b整除,则称a为b的倍数,b为a的约数.几个自然数公有的约数,叫做这几个自然数的公约数.公约数中最大的一个公约 ...

  10. Day01_Java作业

    A:选择题 1:下列标识符哪个是合法的(a) A.class B.$abc C.1234 D.Car.taxi B:填空题 1: java源程序的扩展名是( .java ) 2: java程序经编译后 ...