【TCP】四次挥手(终止连接)

图片

前言

TCP(传输控制协议)是互联网协议(IP)中的一种重要传输层协议,用于在通信的计算机之间建立可靠的、有序的和错误校验的数据传输。在TCP连接中,数据传输是双向的,因此需要一种机制来开始和结束连接。这就是所谓的“握手”和“挥手”。TCP四次挥手是TCP连接断开过程中的一个重要环节,它确保了数据传输的完整性和可靠性。

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

TCP的四次挥手过程发生在两个端点都准备好关闭连接时。以下是四次挥手的详细步骤:

图片

  1. FIN:当一方完成数据发送并决定关闭连接时,它会发送一个FIN报文段,请求关闭连接。此时,发送方进入FIN_WAIT_1状态,等待接收方的确认。

  2. ACK:接收方收到FIN报文段后,会发送一个ACK报文段作为回应,表示同意关闭连接。此时,接收方进入CLOSE_WAIT状态。

  3. FIN:一旦接收方完成所有数据接收并准备关闭连接,它也会发送一个FIN报文段,表示请求关闭连接。此时,发送方进入TIME_WAIT状态。

  4. ACK:接收方发送一个ACK报文段作为回应,确认收到FIN报文段并完成关闭连接。

以下是使用Java代码模拟TCP四次挥手的示例:


import java.io.BufferedReader;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;  
import java.net.Socket;  public class TCPHandshake {  public static void main(String[] args) {  try {  // 创建Socket连接  Socket socket = new Socket("localhost", 8000);  System.out.println("Connected to server");  // 获取输入输出流  BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));  PrintWriter output = new PrintWriter(socket.getOutputStream(), true);  // 第一次挥手:客户端发送FIN报文段请求关闭连接  output.println("FIN");  System.out.println("Sent FIN");  // 等待服务器响应  String response = input.readLine();  System.out.println("Received response: " + response);  // 第二次挥手:服务器发送ACK报文段确认关闭连接请求  output.println("ACK");  System.out.println("Sent ACK");  // 等待客户端响应  response = input.readLine();  System.out.println("Received response: " + response);  // 第三次挥手:客户端发送FIN报文段请求关闭连接  output.println("FIN");  System.out.println("Sent FIN");  // 等待服务器响应  response = input.readLine();  System.out.println("Received response: " + response);  // 第四次挥手:服务器发送ACK报文段确认关闭连接请求  output.println("ACK");  System.out.println("Sent ACK");  // 关闭连接和流  socket.close();  input.close();  output.close();  } catch (Exception e) {  e.printStackTrace();  }  }  
}

第一次挥手:主动关闭方发送关闭请求(FIN)

在TCP的四次挥手过程中,首先由主动关闭方(通常是客户端)发起关闭请求。主动关闭方发送一个TCP报文,其中包含FIN(Finish)标志位,表示主动关闭方不再有数据要发送了。此时,主动关闭方进入FIN_WAIT_1状态,等待被动关闭方的确认。

第二次挥手:被动关闭方回应确认(ACK)

被动关闭方(通常是服务器)接收到主动关闭方的FIN后,发送一个确认(ACK)报文,表示已经收到了关闭请求。此时,被动关闭方进入CLOSE_WAIT状态,表示服务器端的应用程序已经等待关闭了,但仍可以接收来自客户端的数据。

第三次挥手:被动关闭方发送关闭请求(FIN)

在完成自己的数据发送后,被动关闭方也发送一个带有FIN标志的TCP报文,表示被动关闭方也没有数据要发送了。此时,被动关闭方进入LAST_ACK状态,等待主动关闭方的确认。

第四次挥手:主动关闭方回应确认(ACK)

主动关闭方接收到被动关闭方的FIN后,发送一个确认(ACK)报文,表示已经收到了关闭请求。此时,主动关闭方进入TIME_WAIT状态,等待一段时间,以确保被动关闭方收到了确认,并防止可能存在的延迟报文导致连接混乱。一旦等待时间过去,主动关闭方进入CLOSED状态,表示连接已经完全关闭。

为什么挥手需要四次

TCP的四次挥手是为了确保数据流的正确和可靠地关闭。这需要双方都明确地确认关闭请求,并确保所有的数据包都已接收或处理。通过四次握手,每一方都可以确认对方已经完成了数据传输和接收的准备工作。

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

TIME_WAIT状态是TCP四次挥手中的一个重要状态,其持续时间通常是2MSL(最大段生存期)。这是为了确保在网络中的所有数据包都已过期并被丢弃,防止出现旧的数据包在网络中循环并导致连接错误关闭的问题。TIME_WAIT状态也提供了一个机会让发送方等待一段时间,以确保接收方已经收到了关闭连接的请求。

等待2MSL的意义

等待2MSL是为了确保在网络中的所有数据包都已过期并被丢弃。如果发送方在发送完最后一个ACK报文段后立即关闭连接,而网络中仍然存在未过期或未被丢弃的数据包,那么这些数据包可能会在网络中循环并导致连接错误关闭。通过等待2MSL的时间,发送方可以确保这些数据包已经过期并被丢弃,从而避免这种情况的发生。此外,等待2MSL的时间也为接收方提供了一个机会,以确保它已经收到了关闭连接的请求并完成了所有必要的处理工作。

如何解决TIME_WAIT状态过多

最好的办法是尽量让客户端主动断开连接,除非遇到一些异常情况,如客户端协议错误、客户端超时等。

打开系统的TIME_WAIT重用和快速回收。

在Linux系统可以修改以下参数:

1.打开TCP对时间戳的支持,保持服务器与客户端时间同步 

net.ipv4.tcp_timestamps=1(默认即为 1)

2.修改net.ipv4.tcp_tw_reuse = 1,允许对处于TIME_WAIT的socket用于建立新的连接

net.ipv4.tcp_tw_reuse = 1 (默认为0)

修改TIME_WAIT连接状态的上限值,超过上限值,处于TIME_WAIT状态的socket将立刻被清除并打印警告信息。

net.ipv4.tcp_max_tw_buckets = 18000,表示系统同时保持处于TIME_WAIT状态的socket的最大数量,默认为18000。

可修改为更小值。

net.ipv4.tcp_max_tw_buckets = 6666

结语

TCP的四次挥手是一个复杂但必要的过程,用于确保可靠地关闭TCP连接。通过四次握手和TIME_WAIT状态,TCP协议可以确保数据流的正确和可靠地关闭,并避免在网络中循环的数据包导致连接错误关闭的问题。了解TCP的四次挥手过程和状态变迁对于理解TCP协议的工作原理和实现可靠的网络通信至关重要。

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/449833.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端面试拼图-数据结构与算法

摘要:总结一些前端算法题,持续更新! 一、数据结构与算法 时间复杂度-程序执行时需要的计算量(CPU) 空间复杂度-程序执行时需要的内存空间 前端开发:重时间,轻空间 1.把一个数组旋转k步 arr…

第14章_视图

第14章_视图 1.常见的数据库对象 对象描述表(TABLE)表是存储数据的逻辑单元,以行和列的形式存在,列就是字段,行就是记录数据字典就是系统表,存放数据库相关信息的表。系统表的数据通常由数据库系统维护, 程序员通常不…

NUXTJS安装始终报错无法正常运行问题解决

近日在了解NuxtJS,按照官方给出方法进行安装后,不是报错,就是安装成功后运行不了。执行npm run dev后始终运行出错,判断肯定是对应版本问题,沿着这方向研究,最终运行成功了。 文档地址:安装 - …

一篇文章解决你的无线AP选型难题:从入门到精通

无线网络覆盖项目中,无线AP的合理选型和部署非常重要。今天给大家安排。 这篇文章,给你总结了6类典型的无线组网场所,针对每种场景的特点,给出相应的设备选型和部署的方案,同时整理了一些部署无线AP过程中容易忽略的细…

爬虫笔记(三):实战qq登录

咳咳,再这样下去会进橘子叭hhhhhh 以及,这个我觉得大概率是成功的,因为测试了太多次,登录并且验证之后,qq提醒我要我修改密码才可以登录捏QAQ 1. selenium 有关selenium具体是啥,这里就不再赘述了&#x…

奇瑞瑞虎8,是真不能随便碰

文 | AUTO芯球 作者 | 李虎 我是实在看不下去了啊 这奔驰车主砸车 现在开始反转了啊 但卡住我喉咙的是定损5200的奇瑞引擎盖啊 我是真买不起,也不敢买啊 我怕A柱断了,要修20万啊 但我一算,这也不对啊 顶配的报价也只有16.18万啊 如果…

提升 Web 请求效率:Axios request 封装技巧

在开发中,为了提高效率,通常对 Axios 进行封装,简化了请求的发送和对响应的处理。同时,统一错误处理机制有助于维护代码的清晰和一致性。本文介绍了一些高效封装 Axios 请求的方法。 封装理念 通过创建一个请求函数,我…

docker镜像结构

# 基础镜像 FROM openjdk:11.0-jre-buster # 设定时区 ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 拷贝jar包 COPY docker-demo.jar /app.jar # 入口 ENTRYPOINT ["java", "-jar"…

Vue.js 学习14 集成H265web.js播放器实现webpack自动化构建

Vue.js 学习14 集成H265web.js播放器实现webpack自动化构建 一、项目说明1. H265web.js 简介2. 准备环境 二、项目配置1. 下载 H265web.js2. 在vue项目里引入 H265web3. 设置 vue.config.js 三、代码引用1. 参照官方demo , 创建 executor.js2. 在 vue 页面里引用htm…

【C题完整论文】2024美赛完整论文+代码参考(无偿分享)

C题:网球运动中的动力 一、问题分析 1.1 问题一分析 针对该问题,经过数据清洗和特征工程处理之后,即考虑对动量指标的定义,通过数据分析和相关性计算,选取是否发球、是否取得压制性得分、跑动差和失误率这四项指标作…

深入理解Istio服务网格数据平面Envoy

一、服务网格概述(service mesh) 在传统的微服务架构中,服务间的调用,业务代码需要考虑认证、熔断、服务发现等非业务能力,在某种程度上,表现出了一定的耦合性 服务网格追求高级别的服务流量治理能力,认证、熔断、服…

css文本属性

一.颜色(color)(一般用16进制) 二.对齐(text-align) 三.装饰(text-decoration) 四.缩进(text-indent)(一般用2em)(有单位)…