Linux性能学习(4.5):网络_TCP四次挥手内核参数优化

文章目录

  • 1 四次挥手
  • 2 参数优化
    • 2.1 tcp_orphan_retries--->FIN报文重传次数
    • 2.2 tcp_max_orphans--->孤儿连接最大数量
    • 2.3 tcp_fin_timeout--->FINE_WAIT2状态等待时间
    • 2.4 tcp_max_tw_buckets
    • 2.5 tcp_tw_reuse--->复用未释放的端口
  • 3 总结

参考资料:
1. RFC793

在Client和Server断开连接时候,会经历四次交互,称为四次挥手,本篇简单介绍下四次交互。

1 四次挥手

在这里插入图片描述

如上图,客户端和服务端都可以主动先发起close操作,在这里,我们假设Client先发送close操作。

  • 第一次交互:Client和Server都处于ESTABLISHED状态,正常进行通信,此时Client应用程序调用close()或shutdown()来关闭连接。那么内核就会发送FIN报文给到Server。此时Client的状态为FIN_WAIT1;
  • 第二次交互:Server收到FIN报文后,内核自动回复ACK报文。此时Server的状态为CLOSE_WAIT,Client收到ACK之后,状态变为FIN_WAIT2;
  • 第三次交互:Server应用程序调用close函数来关闭连接,并发送SIN报文,此时Server的状态为LAST_ACK;
  • 第四次交互:Client收到FIN之后,回复ACK报文,状态变为TIME_WAIT,等待2MSL后,连接彻底关闭,Server收到ACK后会立马关闭连接。

2MSL的时长为30*2=60s,RFC793定义了MSL为2分钟,Linux设置成了30s,MSL是指报文在网络中的最长生存时间,之所以定义2MSL,是假设发送的ACK丢失,最大消耗一个MSL时间,然后Server端重发一次FIN报文,最大消耗一次MSL事件,那么此时出于TIME_WAIT状态的Client端收到FIN报文后仍然可以发送一次ACK,如果多次丢失,考虑到概率以及性能问题,直接忽略,即只考虑一次丢失。

等待2MSL时间,也不完全是为了数据的重发,而是一种安全保证。如果不等待,立马完全关闭,那么可能被应用程序里面使用这个端口,因为网络因素、Server端重发等因素可能会收到旧的重发的FIN报文,那么新的连接就会被被误关闭;并且也可以防止新的连接收到旧的数据,造成异常。

PS:有时候可能Server收到FIN报文之后,里面close掉,所以可能会出现ACK+FIN在同一个报文中,回复给Client,这时四次握手就变成三次握手了。

PPS:如果Client进程异常退出了,内核就会主动发送RST报文给到Server,然后直接关闭连接,不走正常的四次挥手流程。

2 参数优化

2.1 tcp_orphan_retries—>FIN报文重传次数

当第一次交互时候,如果Client发送FIN包后,一直没有收到Server的ACK,那么就会重发,重发次数受tcp_orphan_retries内核参数控制。

# cat /proc/sys/net/ipv4/tcp_orphan_retries                  
0

默认值为0,表示8次。如果此值大于0,则为正常重试的次数。

如果超过tcp_orphan_retries重试的次数,还没有收到ACK报文,则直接关闭连接。

在第三次交互中,如果Server发送FIN之后,没有收到ACK报文,也会重发,重发次数受tcp_orphan_retries参数控制。

2.2 tcp_max_orphans—>孤儿连接最大数量

当Client端应用程序调用close关闭连接后,此时这个连接已经和应用程序无关了,为孤儿进程,剩下的事由内核来发送FIN包,来和Server进行四次挥手。

那么如果此时发送缓冲区还有数据没有发送完,那么就需要等待发送完,才能把FIN报文发送出去,或者TCP的流控功能,当Server端将接收窗口为0,即Client端不能发送数据,那么Client的连接就会长时间处于FIN_WAIT1状态。

如果一个连接长时间处于FIN_WAIT1状态,就会导致系统资源被长时间占用,因此tcp_max_orphans 参数来定义最大的孤儿连接数量,如果数量大于此值,那么就会直接发送RST报文,不走正常四次握手流程。

# cat /proc/sys/net/ipv4/tcp_max_orphans                     
512

2.3 tcp_fin_timeout—>FINE_WAIT2状态等待时间

当Client收到ACK后,就处于FINE_WAIT2状态,等待Server的FIN报文,此时如果Client应用程序是调用shutdown关闭连接,则一直处于FINE_WAT2状态,在这种状态下,还可以收发数据;如果是调用close关闭的,那么如果超时没有收到FIN报文,就会直接关闭。超时时间受tcp_fin_timeout参数控制。

# cat /proc/sys/net/ipv4/tcp_fin_timeout             
60

2.4 tcp_max_tw_buckets

Client处于TIME_WAIT状态下,会等待2MSL时间然后彻底关闭连接。但是这种状态也会导致系统资源被长时间占用,因此tcp_max_tw_buckets 参数来定义最大的TIME_WAIT状态的连接数量,如果数量大于此值,那么就会直接关闭,不再经历2MSL时间关闭。

# cat /proc/sys/net/ipv4/tcp_max_tw_buckets                  
512

2.5 tcp_tw_reuse—>复用未释放的端口

Client处于TIME_WAIT状态下,这个时候端口仍然被占用,因此应用程序无法使用此端口建立新的连接。因此,可通过tcp_tw_reuse参数来使能可以使用处于TIME_WAIT状态的端口。

# cat /proc/sys/net/ipv4/tcp_tw_reuse                        
0

0关闭,1使能。

另外,如果使能了这个功能,还需要打开TCP时间戳功能,并且需要双方都打开。

# cat /proc/sys/net/ipv4/tcp_timestamps                      
1

3 总结

在这里插入图片描述

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

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

相关文章

tiktok批量发布带货视频工具

tiktok批量发布带货视频工具 今天我们来讲一下最新的 29. 6 版本,这个版本新增视频处理功能,该功能主要新增以下内容,可以替换视频的原音频,可以加背景音乐,可以加视频的内置封面,可以加片头视频&#xff…

Linux Day06

目录 一、printf输出问题 二、复制进程fork 2.1进程 2.2 pid_t fork(void); 注意: 2.3逻辑地址和物理地址 2.4写时拷贝技术 一、printf输出问题 printf 函数并不会直接将数据输出到屏幕,而是先放到缓冲区中,只有一下三种情况满 足&a…

Maven发布项目到Nexus私服

项目pom配置 在项目pom.xml中文件中的仓库配置&#xff0c;Nexus私服如何搭建在这里不介绍了可自行百度。 <distributionManagement><repository><id>releases</id><name>Nexus Release Repository</name><url>http://私服地址:34…

STM32 CubeMX USB_CDC(USB_转串口)

STM32 CubeMX STM32 CubeMX 定时器&#xff08;普通模式和PWM模式&#xff09; STM32 CubeMX一、STM32 CubeMX 设置USB时钟设置USB使能UBS功能选择 二、代码部分添加代码实验效果 ![请添加图片描述](https://img-blog.csdnimg.cn/a7333bba478441ab950a66fc63f204fb.png)printf发…

nginx部署以及反向代理多域名实现HTTPS访问

nginx部署以及反向代理多域名实现 1.nginx部署 1.1 编写nginx部署文件 docker-compose.yml version: 3 services: nginx:restart: always image: nginx:1.20container_name: nginx-mainports:- 80:80- 443:443volumes: # 基础配置- /opt/nginx_main/nginx-info/nginx.conf:/…

C++QT教程2——创建QT项目

文章目录 2 创建Qt项目2.1 使用向导创建2.2 手动创建2.3 .pro文件2.4 一个最简单的Qt应用程序main入口函数中&#xff08;main.cpp&#xff09;arnold_widget.h函数arnold_widget.cpp 参考文章 2 创建Qt项目 2.1 使用向导创建 打开Qt Creator 界面选择 New Project或者选择菜…

在IDEA同一个窗口中同时打开多个独立项目

文章说明 本文主要说明如何在Intellij Idea中同时打开多个独立的Maven项目。 我在使用idea的时候&#xff0c;由于自己负责了很多项目&#xff0c;经常要在不通的代码之间切换来切换去。然后搜索代码的时候也只能搜到当前打开的这个项目。因为这个原因&#xff0c;一些小项目…

策略模式:优雅地实现可扩展的设计

策略模式&#xff1a;优雅地实现可扩展的设计 摘要&#xff1a; 策略模式是一种常用的设计模式&#xff0c;它可以帮助我们实现可扩展的、灵活的代码结构。本文将通过一个计算器案例来介绍策略模式的概念、使用场景以及如何在实际项目中应用策略模式来提高代码的可维护性和可扩…

Babylon.js开发工具链大全

本文介绍Babylon 团队&#xff08;JS 和原生&#xff09;和社区共同创建的所有出色工具的摘要&#xff0c;以帮助开发人员和设计人员创建出色的 3D 体验。 推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 1、Sandbox 第一个工具Sandbox可能是最简单的&#xff0c;它实…

vue diff 前后缀+最长递增子序列算法

文章目录 查找相同前后缀通过前后缀位置信息新增节点通过前后缀位置信息删除节点 中间部份 diff判断节点是否需要移动删除节点删除未查找到的节点删除多余节点 移动和新增节点最长递增子序列 求解最长递增子序列位置信息 查找相同前后缀 如上图所示&#xff0c;新旧 children 拥…

ubuntu18.04安装docker及docker基本命令的使用

官网安装步骤&#xff1a;https://docs.docker.com/desktop/install/ubuntu/ docker快速教程 Ubuntu-Docker安装和使用 docker-hub 1、常用指令 &#xff08;1&#xff09;镜像操作 # ############################# 以nginx为例 docker images docker pull nginx:1.24 dock…

xLua学习

xLua教程&#xff1a;https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/XLua%E6%95%99%E7%A8%8B.md xLua配置&#xff1a;https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/configure.md FAQ&#xff1a;https://github.com/Tencent/xLua/blob/maste…