当前位置: 首页 > news >正文

深入协议栈了解TCP的三次握手、四次挥手、CLOSE-WAIT、TIME-WAIT。

        TCP网络编程的代码网上很多,这里就不再赘述,简单用一个图展示一下tcp网络编程的流程:        

1、深入connect、listen、accept系统调用,进一步理解TCP的三次握手

        这三个函数都是系统调用,我们可以分为请求连接方和被动连接两部分,我们知道请求连接方并非都是client,为了方便,本文用client代表主动连接方,server代表被动连接方。   

  • connect()是client的请求连接函数;处理client端的三次握手
  • listen()是server用来监听client端有没有连接请求,本质上它是监测半连接队列和全连接队列中有没有信息,这两个队列中存放的是需要和server端进行连接的客户端信息,下文对这两个队列有解释。下图listen函数的解析中可以看到,第二个参数backlog表示等待连接队列的最大长度。

  • accept()是server端为了独立管理每一个client连接,为其请求分配fd的函数,此函数调用时其实三次握手已经完成了。它从全连接队列中取出第一个节点,并为其分配fd。详情见下图

1、三次握手发生在那个函数?

   

  • 三次握手具体流程:
    • client端调用connect系统调用,发起连接请求,并阻塞等待返回结果;
    • server端协议栈收到client端发来的syn请求报文后,将该client的tcb信息放入半连接队列,并回复client端syn+ack;
    • client端的connect系统调用回复server端ack;
    • server端收到client端发来的确认ack后,从半连接队列中找到此client对应的tcb,修改其连接状态,并放入全连接队列中,此时协议栈层面的三次握手完成。

        因此对于client而言,三次握手发生在connect函数中;对于server而言,三次握手是由协议栈实现,不发生在任一网络编程函数中

2、listen(fd, backlog)中,第二个参数backlog是什么意思?

        经过对协议栈的分析,它首先创建一个半连接队列,存储发送了syn请求报文的client的信息,然后创建了一个全连接队列,存储回复了ack报文的client的信息(这个信息是从半连接队列中迁移来的),此时协议栈层面的三次握手已经完成;

        对于server来说,所有的client连接都会进行业务交互,但是这两个队列中的client连接都还未交由server的用户态管理,因此它们还都属于待连接状态,所以等待连接队列=半连接队列+全连接队列

       根据上述listen的函数解析和协议栈原理分析得知,backlog是等待连接队列的最大长度,即=半连接队列+全连接队列的最大长度和

3、accept函数的作用是什么?accept是如何分配fd的?

  1. 由上述函数解析和三次握手分析得,accept的作用为:
    1. 从全连接队列中取出第一个节点信息(tcb);
    2. 根据tcb信息为其重新分配一个sockfd。
  2. accept如何分配的fd:根据取出的tcb中的ip、port等信息,创建一个新的sockfd接收这个连接,交由server管理(多路io复用epoll)。

4、什么是半连接队列与全连接队列?

        半连接队列:由协议栈创建并管理,存放只发送来了syn请求报文的client的tcb信息

        全连接队列:由协议栈创建并管理,存放已经回复了ack确认报文的client的tcb信息。

2、深入TCP的四次挥手原理,进一步理解time_wait/close_wait状态

 

         我们要明确一点,close()关闭的只是sockfd(文件句柄,五元组),那tcp连接怎么断开呢?从accept函数我们可以知道,server为每一个连接tcb都分配了一个与之对应的sockfd,当server关闭了这个sockfd之后,与之对应的tcb也被删除,若server没有调用close()关闭sockfd,则这个连接就一直存在,除非等到系统超时或出现网络异常

        RFC 793 - Transmission Control Protocol

1、什么是四次挥手?为什么这样做?

  • 四次挥手过程:主动断开放用client表示,被动断开方用server表示
    • client调用close()函数,向server发送fin请求报文,client进入fin_wait_1状态;
    • server的协议栈收到fin后立即回应client一个ack报文,server进入close_wait状态;
    • server应用层得知recv() == 0时,及时调用close() 函数向client发送fin报文,server进入last_ack状态;
    • client收到fin报文后,立即回应server一个ack报文,client进入time_wait状态。
  • 四次挥手的原因:
    • server连接关闭的控制权在应用层,即调用close()后关闭,立即回复ack是协议栈的操作,所以两者不能做到同步。

2、什么是close_wait状态?产生大量close_wait的原因是什么?如何解决?

  • close_wait是server端的状态,表示等待来自本地用户的连接终止请求,从server的协议栈回复ack后到用户层调用close()关闭连接之前这段时间称为close_wait状态
  • 大量close_wait原因:收到client的断开请求报文(判断recv()== 0)后,没有调用或没有及时调用close()关闭连接。
  • 解决:收到client的断开请求报文(判断recv()== 0)后立即调用close(),在这之间不要出现多余的业务处理,如果无法避免就将业务抛给其他线程进行处理。

3、什么是time_wait状态?产生大量time_wait的原因是什么?如何解决?

  • time_wait是client端的状态,表示等待足够的时间,以确保远程tcp接收到对其连接终止请求的确认。client给server回复ack报文后,就进入到time_wait状态
  • 大量time_wait的原因:一般只有服务器或中间服务层才会出现大量对外链接,因此服务端主动发起大量短链接关闭,导致服务端存在大量的time_wait状态(比如HTTP)。
    •  HTTP默认的Connection值为close,那么就意味着关闭请求的一方几乎都会是由服务端这边发起的。那么这个服务端产生TIME_WAIT过多的情况就很正常了。

    • 虽然HTTP默认Connection值为close,但是,现在的浏览器发送请求的时候一般都会设置Connection为keep-alive了。所以,也有人说,现在没有必要通过调整参数来使TIME_WAIT降低了。 

  • 解决:
    • 1、规避大量短链接的使用,
    • 2、修改/etc/sysctl.conf文件,让服务器能够快速回收和重用那些time_wait的资源。

4、close_wait/time_wait的时长各自是多少?有什么作用?

  • 时长:
    • close_wait:如果没有调用close()至少存在两个小时,直到系统崩溃。如果没有及时调用close(),那就得看具体的业务处理时长。

    • time_wait:2MSL,RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

      • 将TCP TIME-WAIT超时时间修改为小于60秒与TCP/IP协议quiet time概念相违背,可能导致您的系统将旧数据当做新数据接收,或者复制的新数据当做旧数据拒绝。因此请在网络专家建议下调整。

      • 你可以通过运行netstat -ant | grep TIME_WAIT | wc -l命令判断服务器中是否存在大量短连接,然后再确定要不要修改。

      • 修改 TIME-WAIT时间的方法有两种:

      • echo 5 > /proc/sys/net/ipv4/tcp_tw_timeout
      • sysctl -w "net.ipv4.tcp_tw_timeout=5"
  • 作用:      
    • close_wait:等待来自本地用户的连接终止请求。

    • time_wait:等待足够的时间,以确保远程tcp接收到对其连接终止请求的确认。

5、出现大量close_wait/time_wait的危害是什么?

        close_wait:1、如果因为没有调用close()导致存在大量close_wait,那将会消耗系统资源,导致系统崩溃;2、如果因为没有及时调用close(),则危害和time_wait一样。

        time_wait:占用的端口不能及时释放被使用,要等到2MSL时间后才能使用,则没有足够的sockfd分配,将大大降低并发量。

        所以它们有一个共同的危害就是“占着茅坑不拉屎”,资源得不到充分利用。

本文说提到的client和server不是表面上的客户端与服务器,client是主动请求方;server是被动响应方。

相关文章:

深入协议栈了解TCP的三次握手、四次挥手、CLOSE-WAIT、TIME-WAIT。

TCP网络编程的代码网上很多,这里就不再赘述,简单用一个图展示一下tcp网络编程的流程: 1、深入connect、listen、accept系统调用,进一步理解TCP的三次握手 这三个函数都是系统调用,我们可以分为请求连接方和被…...

接口自动化测试系列-yml管理测试用例

项目源码 目录结构及项目介绍 整体目录结构,目录说明参考 测试用例结构类似httprunner写法,可参考demo 主要核心函数 用例读取转换json import yaml import main import os def yaml_r():curpath f{main.BASE_DIR}/quality_management_logic/ops_ne…...

开源对象存储系统minio部署配置与SpringBoot客户端整合访问

文章目录 1、MinIO安装部署1.1 下载 2、管理工具2.1、图形管理工具2.2、命令管理工具2.3、Java SDK管理工具 3、MinIO Server配置参数3.1、启动参数:3.2、环境变量3.3、Root验证参数 4、MinIO Client可用命令 官方介绍: MinIO 提供高性能、与S3 兼容的对…...

Matlab之数组字符串函数汇总

一、前言 在MATLAB中,数组字符串是指由字符组成的一维数组。字符串可以包含字母、数字、标点符号和空格等字符。MATLAB提供了一些函数和操作符来创建、访问和操作字符串数组。 二、字符串数组具体怎么使用? 1、使用单引号或双引号括起来的字符序列 例…...

基于深度学习网络的火灾检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................................ load F…...

【Linux】高级IO和多路转接 | select/poll/epoll

多路转接和高级IO 咳咳,写的时候出了点问题,标点符号全乱了(批量替换了几次),干脆就把全文的逗号和句号都改成英文的了(不然代码块里面的代码都是中文标点就跑不动了) 1.高级IO 1.1 五种IO模型…...

el-select 支持多选 搜索远程数据 组件抽取

el-select 支持多选 搜索远程数据 组件抽取 使用方式 import selectView from ./components/selectView<el-form><el-form-item label"选择器"><selectView v-model"selValue" change"handleChange"></el-form-item> …...

el-table纵向垂直表头

参考&#xff1a;https://www.jianshu.com/p/1f38eaffd070 <el-tablestyle"width: 100%":data"getValues":show-header"false"border:cell-style"cellStyle" ><el-table-columnv-for"(item, index) in getHeaders"…...

Pinyin4j介绍和简单使用

前言 Pinyin4j是一个Java库&#xff0c;用于将汉字转换为拼音。它是由中国清华大学的Tsinghua University和中国科学院计算技术研究所的研究人员开发的。Pinyin4j可以用于Java应用程序中&#xff0c;以便在需要时将汉字转换为拼音。例如&#xff0c;它可以用于中文输入法、文本…...

【数据结构】查找

【数据结构】查找 数据结构中&#xff0c;有顺序查找、二分查找、散列查找、插值查找、斐波那契额查找 1.顺序查找 条件&#xff1a;待查找的元素与数组中的元素按顺序排列。算法&#xff1a;从数组的第一个元素开始&#xff0c;逐个比较&#xff0c;直到找到目标元素或遍历完…...

第一次面试

1.多态的原理 2.编译原理 3.HTTPS的加密原理 4.说一说C11新特性 5.平时用过哪些STL容器 6.STL的比较器 原来就是自定义工具类hhhhhh 7.函数指针用过吗 8.I/O多路复用 9.Redis 问的基本都背过&#xff0c;但是一紧张啥都忘了hhhhhhhhh...

Nacos配置文件更新+热更新+多环境配置共享+集群搭建

对服务配置文件 场景&#xff1a; 如果多个服务对应的配置文件都需要更改时&#xff0c;可以利用配置管理&#xff0c;方便对配置文件进行更新&#xff0c;而且是在本地配置前先读取nacos的配置文件&#xff0c;优先级大于本地配置文件 配置步骤 1.首先在Nacos中的配置列表中增…...

李宏毅-机器学习hw4-self-attention结构-辨别600个speaker的身份

一、慢慢分析学习pytorch中的各个模块的参数含义、使用方法、功能&#xff1a; 1.encoder编码器中的nhead参数&#xff1a; self.encoder_layer nn.TransformerEncoderLayer( d_modeld_model, dim_feedforward256, nhead2) 所以说&#xff0c;这个nhead的意思&#xff0c;就…...

记一次使用NetworkManager管理Ubuntu网络无效问题分析

我们都知道CentOS、Redhat系列网络配置比较连贯&#xff0c;要么在/etc/sysconfig/network-scripts/ifcfg-网络设备名&#xff0c;文件中编辑后&#xff0c;重启网络服务&#xff1b;要么使用nmtui或者nmcli进行配置。但是&#xff0c;Ubuntu变动就比较大&#xff1a; 早期版本…...

Nginx重写功能

Nginx重写功能 一、Nginx常见模块二、访问路由location2.1location常用正则表达式2.2、location的分类2.3、location常用的匹配规则2.4、location优先级排列说明2.5、location示例2.6、location优先级总结2.7、实例2.7.1、location/{}与location/{}2.7.2、location/index.html{…...

王道考研计算机网络

文章目录 计算机网络体系结构计算机网络概述计算机网络的性能指标 计算机网络体系结构与参考模型错题 物理层通信基础基础概念奈奎斯特定理和香农定理编码与调制电路交换、报文交换和分组交换数据报与虚电路 传输介质物理层设备错题 数据链路层数据链路层的功能组帧差错控制检错…...

数据链路层重点协议-以太网

以太网简介 "以太网" 不是一种具体的网络&#xff0c;而是一种技术标准&#xff1b;既包含了数据链路层的内容&#xff0c;也包含了 一些物理层的内容。例如&#xff1a;规定了网络拓扑结构&#xff0c;访问控制方式&#xff0c;传输速率等&#xff1b; 以太网数据帧…...

学习计划

白驹过隙&#xff0c;转眼已是大二。新学期&#xff0c;新气象&#xff0c;新计划。 一、专业学习方面 学习vue、spring boot、redis、MybatisPlus、Elasticsearch、ssm框架&#xff0c;完成项目的编写&#xff0c;思考复盘。 二、读书方面 因为我大概率会走前端方向&#xff0…...

RabbitMQ的RPM包安装和Python读写操作

下载地址 ## erlang 下载地址 https://packagecloud.io/rabbitmq/erlang?page6## rabbitmq 下载地址 https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/7/rabbitmq-server-3.8.29-1.el7.noarch.rpm?distro_version_id140 Rabbitmq的RPM包安装 ## 下载 wget -…...

文件上传漏洞案例

目录 1.案例一 1&#xff09;案例源码 2&#xff09;创建web.php文件 3&#xff09;使用抓包软件 2.案例二 1&#xff09;案例代码 2&#xff09; 案例分析 3&#xff09;copy命令生成图片马 4&#xff09;上传图片马到服务器 5&#xff09;解析 文件图片 3.案例三 …...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

作为点的对象CenterNet论文阅读

摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表&#xff0c;并对每一个位置进行分类。这种做法既浪费又低效&#xff0c;并且需要额外的后处理。在本文中&#xff0c;我们采取了不同的方法。我们将物体建模为单…...