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

linux重启网络(systemctl restart network)会不会导致连接断开?

一、实验代码:

server.go:

package mainimport ("context""fmt""math/rand""net/http""os""os/signal""syscall""time"
)func HelloHandler(w http.ResponseWriter, r *http.Request) {fmt.Printf("%s cli=%s\n", time.Now().Format(time.DateTime), r.RemoteAddr)time.Sleep(60*time.Second)	fmt.Fprintf(w, "Hello %s\n", r.RemoteAddr)
}func main() {http.HandleFunc("/", HelloHandler)server := &http.Server{Addr: ":8000", Handler: nil}done := make(chan bool, 1)sigs := make(chan os.Signal, 1)signal.Notify(sigs,syscall.SIGKILL,syscall.SIGTERM,syscall.SIGINT,syscall.SIGHUP,syscall.SIGUSR1,syscall.SIGUSR2)go func() {for sig := range sigs {fmt.Printf("%s catch signal:%v\n", time.Now().Format(time.DateTime), sig)if sig == syscall.SIGINT || sig == syscall.SIGTERM || sig == syscall.SIGKILL {r := rand.Intn(3)time.Sleep(time.Duration(3+r) * time.Second)ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)defer cancel()fmt.Printf("%s shutdown start\n", time.Now().Format(time.DateTime))server.Shutdown(ctx)fmt.Printf("%s shutdown end\n", time.Now().Format(time.DateTime))done <- truereturn}}}()fmt.Printf("%s server start\n", time.Now().Format(time.DateTime))server.ListenAndServe()fmt.Printf("%s server end\n", time.Now().Format(time.DateTime))<-done
}

客户端请求:

在另一台机器执行:

$ curl '192.168.101.6:8000'
Hello 192.168.101.1:57059

二、重启网口设备并观察:

在客户端执行curl请求的60s间隔内执行以下命令:

netstat -enplta | grep 8000 && ip link set ens33 down && sleep 5 && ip a && sleep 20 && ip link set ens33 up && sleep 5 && ip a && netstat -enplta | grep 8000

查看输出:

三、参考解释:

问AI:为什么linux重启network不会断开tcp静默连接?

豆包回答:

从你提供的命令执行日志来看,核心现象是:将网卡ens33彻底断开(down)20 秒后重新启用(up),8000 端口的 TCP 连接(包括LISTEN监听状态和ESTABLISHED已建立连接)依然保持,未被中断。这一现象的本质是 Linux 内核对 TCP 连接状态的 “持久化维护”+ 网卡操作不破坏核心连接信息,具体可从 4 个关键维度拆解:

一、核心前提:ip link down/up仅操作 “链路层”,不清除内核连接状态

ip link set ens33 down的作用是禁用网卡的链路层传输能力(即无法发送 / 接收物理帧),但不会影响内核中已存在的 TCP 连接信息和进程持有的 Socket 句柄。从日志和内核机制可明确两点:

  1. TCP 连接状态由内核而非网卡维护

TCP 连接的本质是内核中的 “连接结构体”(包含四元组:源 IP / 端口、目的 IP / 端口 + 连接状态如ESTABLISHED),以及进程(如你的3338/./server)持有的Socket 文件描述符。只要进程不退出、Socket 不主动关闭,内核就会持续保留这些信息 —— 哪怕网卡暂时无法传输数据。

  • 你的server进程(PID 3338)在整个操作中始终运行,未被终止,因此LISTEN状态的 Socket(绑定 8000 端口)和ESTABLISHED状态的连接结构体,全程被内核保留。

  • down不释放 IP 地址,四元组保持不变

  1. 从日志可见:

    • ens33 down时,IP 地址192.168.101.6/24仍显示valid_lft forever(未释放);
    • ens33 up后,IP 未变化,仍为192.168.101.6。TCP 连接的 “四元组”(192.168.101.6:8000 ↔ 192.168.101.1:57059)全程未被破坏,内核无需重新建立连接,只需在网卡恢复后继续使用原有四元组传输数据。

二、TCP 协议超时机制:20 秒远未达到 “连接失效” 阈值

网卡down的 20 秒内,链路中断导致数据包无法传输,但 TCP 的超时重传机制会 “容忍” 这一短暂中断,不会判定连接失效:

  1. TCP 重传超时(RTO)远大于 20 秒

Linux 内核中,TCP 连接的 “失效判定” 依赖于tcp_retries2参数(默认值 15),该参数控制 “已建立连接后,数据包丢失时的重传次数”,对应总超时时间约15 分钟(通过指数退避算法计算,初始 RTO 约 1 秒,每次重传后 RTO 翻倍,15 次重传后总耗时达十几分钟)。

  • 你的操作仅中断 20 秒,远未达到 TCP 的 “连接失效” 阈值,内核会暂时缓存待发送的数据包,等待网卡恢复后自动重传,而非主动断开连接。

  • 无数据传输时,TCP 不触发即时断连

  1. 你的场景中,ESTABLISHED连接是 “静默连接”(无主动发包),网卡中断期间没有数据包需要传输,因此 TCP 甚至不会触发重传 —— 内核仅需维持连接状态,等待链路恢复后继续 “待命”。

三、进程与 Socket 的绑定:server进程未退出,监听状态持续

LISTEN状态的连接(:::8000)之所以始终存在,核心是 **server进程(PID 3338)未终止 **:

  • 进程启动时,通过bind()系统调用将 Socket 绑定到 8000 端口,并通过listen()进入监听状态;
  • 只要进程不退出(未收到SIGTERM/SIGKILL信号,未崩溃),Socket 就会持续处于 “打开” 状态,内核会保留该 Socket 的监听配置;
  • ip link down/up不会向进程发送 “关闭 Socket” 的信号(除非进程主动注册了网卡状态变化的回调,但普通server程序不会这么做),因此监听状态全程不变。

四、链路恢复后的 “无缝衔接”:IP 与路由快速复用

ip link set ens33 up后,网卡恢复链路层能力,此时:

  1. IP 地址无需重新获取

  • 如日志所示,ens33的 IP(192.168.101.6)未释放,因此无需通过 DHCP 重新申请 IP,省去了 “地址协商” 的耗时(通常 3-5 秒),连接可立即恢复数据传输。

  • 路由表自动恢复

  1. 网卡up后,内核会自动恢复原有的路由规则(如默认网关、局域网路由),192.168.101.6192.168.101.1之间的通信路径立即通畅,TCP 连接可直接复用原有路由发送 / 接收数据。

延伸验证:若想让连接断开,需要做什么?

从上述机制可反推,只有破坏以下任一条件,连接才会中断:

  1. 终止server进程:执行kill -9 3338,进程退出后会关闭所有持有的 Socket,LISTENESTABLISHED连接会被内核清除;
  2. 延长网卡中断时间:若ens33 down超过 15 分钟(TCPtcp_retries2对应的总超时),内核会判定 “连接失效”,主动发送FIN报文断开ESTABLISHED连接;
  3. 修改 IP 地址down网卡后执行ip addr del 192.168.101.6/24 dev ens33,再up并配置新 IP,TCP 四元组被破坏,连接无法恢复;
  4. 主动关闭 Socket:在server程序中调用close()关闭 8000 端口的 Socket,或客户端(192.168.101.1)主动断开连接。

总结

你观察到的现象,是 Linux 内核 “分层设计” 的典型体现:链路层(网卡)的短暂中断,不会影响传输层(TCP)和应用层(进程)的核心状态。只要进程不退出、TCP 未超时、IP 与四元组保持不变,即使网卡断开再恢复,连接也能 “无缝续接”—— 这也是 Linux 作为服务器操作系统,能提供高可靠网络服务的重要原因之一。

四、进一步思考:网络驱动和协议栈的区别

豆包回答:

在 Linux 网络体系中,网络驱动程序协议栈程序是两个核心组件,分别负责不同层面的工作,二者协作完成 “从硬件到应用” 的网络数据传输。简单说:驱动程序是 “硬件的翻译官”,负责与网卡硬件直接交互;协议栈程序是 “数据的处理中心”,负责解析和封装网络协议(如 IP、TCP)。具体区别可从 6 个维度清晰区分:

一、工作层级:底层硬件交互 vs 上层协议处理

  • 网络驱动程序:工作在链路层(L2),是操作系统内核与网卡硬件之间的 “桥梁”,直接操作网卡的物理接口(如 PCIe 总线、PHY 芯片),处理最原始的 “帧(Frame)” 数据(如以太网帧)。

  • 举例:当网卡收到一根网线传来的电信号时,驱动程序负责将电信号转换成二进制数据帧,并传递给上层;发送数据时,驱动将上层传来的帧转换成电信号,通过网卡硬件发送出去。

  • 协议栈程序:工作在网络层(L3)、传输层(L4)及以上,是纯软件逻辑,基于驱动提供的链路层接口,处理各种网络协议(如 IP、TCP、UDP、ICMP 等)。

  • 举例:当驱动传来一个以太网帧时,协议栈先解析帧头(如 MAC 地址),提取内部的 IP 数据包;再解析 IP 头(如源 / 目的 IP),确定路由;若上层是 TCP,再解析 TCP 头(如端口、序列号),最终将数据交给应用程序(如浏览器)。

二、核心功能:控制硬件 vs 处理协议逻辑

  • 网络驱动程序的核心功能

    1. 硬件初始化:加载时检测网卡硬件(如读取 PCIe 设备 ID),初始化网卡寄存器(如配置 MAC 地址、MTU、速率协商)。
    2. 数据收发:实现帧的发送(将上层数据封装成物理帧,通过 DMA 传输到网卡缓冲区)和接收(从网卡缓冲区读取帧,传递给协议栈)。
    3. 硬件中断处理:当网卡收到数据或发生错误(如链路断开)时,触发硬件中断,驱动程序响应中断(如读取数据、上报错误状态)。
    4. 硬件状态管理:监控网卡状态(如链路是否 UP、速率是否 1Gbps),提供ethtool等工具的查询接口(如ethtool ens33查看网卡信息)。
  • 协议栈程序的核心功能

    1. 协议封装与解析:发送数据时,按协议逐层封装(应用数据→TCP 段→IP 包→以太网帧);接收时反向解析,剥离各层头部。
    2. 路由与转发:根据 IP 地址和路由表,确定数据的下一跳(如通过routeip route配置的规则)。
    3. 连接管理:对 TCP 等面向连接的协议,维护连接状态(如三次握手、四次挥手、超时重传、拥塞控制)。
    4. 流量控制:实现 TCP 滑动窗口、拥塞窗口等机制,避免网络拥塞;对 UDP 等无连接协议,仅做简单的端口映射。

三、交互对象:硬件设备 vs 驱动和应用程序

  • 网络驱动程序:直接与网卡硬件(物理芯片、寄存器、缓冲区)交互,同时向上提供接口给协议栈(通过内核的net_device结构体,暴露hard_start_xmit等发送函数)。

  • 它不理解 “IP 地址”“端口号”,只认识 “MAC 地址” 和 “帧”。

  • 协议栈程序:向下依赖驱动程序提供的链路层接口(如调用驱动的发送函数传递帧),向上为应用程序提供 Socket 接口(如socket()send()recv())。

  • 它不关心 “电信号”“网卡寄存器”,只处理 “数据包” 和 “协议规则”。

四、代码实现:硬件相关 vs 协议通用

  • 网络驱动程序:代码高度依赖具体网卡型号,不同厂商(如 Intel、Broadcom)、不同型号(如 Intel I219、Broadcom BCM5720)的驱动逻辑差异极大,需适配硬件手册定义的寄存器和功能。

  • 例如:Intel 网卡驱动e1000e和 Realtek 网卡驱动r8169的代码几乎完全不同,分别对应各自的硬件规格。

  • 协议栈程序:代码是通用的协议实现,与具体硬件无关。无论用哪种网卡,TCP/IP 协议的逻辑(如 IP 路由算法、TCP 重传机制)完全一致。

  • 例如:Linux 内核的net/ipv4/目录下的tcp.c(TCP 实现)、ip_forward.c(IP 转发),对所有网卡都通用。

五、故障表现:硬件层面 vs 协议层面

  • 驱动程序故障:通常表现为硬件不可用或链路异常,例如:

    • 网卡无法识别(ip link看不到设备);
    • 链路始终DOWNip link show ens33显示state DOWN);
    • 频繁丢帧(ethtool -S ens33显示rx_dropped持续增长);
    • 速率协商失败(只能工作在 10Mbps,无法达到 1Gbps)。
  • 协议栈程序故障:通常表现为数据传输异常但硬件正常,例如:

    • ping通 IP 但无法建立 TCP 连接(可能 TCP 端口被过滤或协议栈状态异常);
    • 路由错误(ping 8.8.8.8显示 “网络不可达”,但ip link显示链路 UP);
    • TCP 超时重传频繁(ss -ti显示retrans字段增长,可能拥塞控制逻辑异常);
    • DNS 解析失败(应用层协议处理异常,但网卡能正常收发数据)。

六、依赖关系:协议栈依赖驱动,驱动不依赖协议栈

  • 协议栈的所有数据收发,最终都需要通过驱动程序与硬件交互(没有驱动,协议栈就是 “无米之炊”)。
  • 驱动程序的核心功能(如初始化网卡、收发帧)不依赖协议栈,即使协议栈未加载,驱动也能单独工作(例如:通过raw socket直接操作驱动发送帧,无需经过 IP 协议)。

总结:一句话区分

网络驱动程序是 “硬件的执行者”,负责将抽象的 “帧” 转换成物理信号,让数据能在网线 / 无线中传输;

协议栈程序是 “规则的制定者”,负责将应用数据按网络协议(IP/TCP 等)拆解、封装,让数据能跨越网络找到目标。

二者就像 “快递员” 和 “物流系统”:驱动是快递员(负责把包裹送到物理地址),协议栈是物流系统(负责规划路线、处理包裹信息,确保包裹送到正确的人手里)。

--end--

http://www.dtcms.com/a/483852.html

相关文章:

  • 怎么用云服务器建设网站wordpress 商务主题
  • Monitoring: 1靶场渗透
  • 网店网站建设哪家小吃培训机构排名前十
  • 科技类网站源码百度h5游戏中心
  • 对伯努利过程的理解
  • 临沂网站建设步骤广州网站建设推广公司有哪些
  • 法律网站的建设流程提交网址
  • 广州市住房和城乡建设厅网站首页怎么注册微网站吗
  • 10年网站设计祥汇云江西建设厅网站查询施工员
  • dedecms网站关键词网址之家哪个好
  • Linux1014 shell:sed c s/ ,#!/bin/sed -f ./sed.sh 1.txt ,1.sed 1.txt, ,
  • HyperWorks许可证与其他软件的卓越集成
  • 辽源建站公司免费聊天软件
  • 如何让便笺实现开机自启动
  • 工业网站模板wordpress 不在根目录
  • 湖北智能网站建设找哪家图床外链生成器
  • 做销售如何在网站上搜集资料织梦网站后台模版更换
  • 做网站最快的编程语言注册wordpress账号
  • MobiOffice解锁高级功能版 v15.9.57971 安卓手机doc, docx ppt, .pptx pdf办公软件
  • 机关网站建设的作用三亚网站建设哪家专业
  • java数据结构--时间和空间复杂度
  • 运城市建设局网站长春火车站停运了吗
  • 网吧可以做网站吗文字控图片在线制作
  • FC红白机游戏下载:1000多款FC小游戏打包下载
  • 实体店做网站有用吗新郑建设局网站
  • 长沙市建设网站网站建设平台接单
  • 网站改版什么意思免费做网站网站
  • 北京哪家公司做网站好网站开发的毕业周记
  • 为什么Java不支持多继承
  • 【编译原理笔记】2.1 Programming Language Basics