当前位置:首页 > 文章列表 > 文章 > linux > systemd ListenStream 与 ListenDatagram 怎么选

systemd ListenStream 与 ListenDatagram 怎么选

来源:17golang原创 2026-11-14 06:24:14 0浏览 收藏

ListenStream= 与 ListenDatagram= 应按服务期待的 socket 类型选择:IP 地址上的 TCP 用 ListenStream,UDP 用 ListenDatagram;Unix 本地 socket 也分别有流式和数据报类型。端口相同、路径相似都不代表可以互换。选择之前,还要确认服务能接收 systemd 传入的 socket,而不是只会自己创建并绑定端口。

官方地址:https://systemd.io/

问题:服务需要字节流,还是一条条数据报

面对一个监听配置,先问程序使用什么协议和读写模型。TCP 服务通常在监听 socket 上接受连接,再从连接中读取连续字节;UDP 服务则接收一条条数据报。把 ListenStream 改成 ListenDatagram,不会替程序完成协议转换,也不会让原本的 TCP 客户端自动变成 UDP 客户端。

本地文件路径同样不能决定类型:Unix 字节流与 Unix 数据报都可以使用路径形式地址。命名为 control.sock 的文件既可能对应流式协议,也可能对应数据报协议,需要与程序约定一致。本文按“小配方、关键配置、变体与完整片段”组织,便于按实际服务选择。

最小配方:先用明确的回环地址

假定程序支持原生 socket activation,并且需要接管 TCP 监听 socket,可准备如下 example-daemon.socket。这是配置骨架,不包含可直接运行的服务程序。

# example-daemon.socket:本例按 TCP 字节流创建监听端点。
[Unit]
Description=Example stream socket

[Socket]
ListenStream=127.0.0.1:9123
Accept=no

[Install]
WantedBy=sockets.target

这里显式绑定 127.0.0.1,表示 IPv4 本机回环。只写端口数字可能涉及 IPv6 与双栈行为,不能把它直接理解成只对本机监听。实际监听范围应按服务需要单独确定。

如果服务使用 UDP,可把同一个文件的 Socket 段替换成下面内容。注意是二选一的变体,并非追加一个同端口的流式监听后就完成了兼容。

# UDP 变体:替换上面的 [Socket] 段,不要同时保留 ListenStream。
[Socket]
ListenDatagram=127.0.0.1:9123
Accept=no

关键配置:类型、地址和接管模式分别决定什么

配置维度回答的问题本文选择
ListenStream/ListenDatagramsocket 的读写语义是什么根据程序协议二选一
IP 或 Unix 路径在哪个地址族监听示例先用 IPv4 回环
Accept谁负责接受流式连接no,由服务接管监听 socket
service 对应关系激活哪个程序使用同名 service
ListenStream和ListenDatagram在IP与Unix地址中的对应关系
监听类型与地址族的静态对应说明图。看配置类型与两种地址族的连线,协议不能只从端口或文件名推断。

Accept=no 时,systemd 把监听 socket 交给一个服务管理。对于流式 socket,Accept=yes 是另一种模型:每条连接激活一个模板服务实例,传入的是已连接 socket。它要求对应的模板服务与程序处理模型配套,不适合只改一行就套用。

数据报 socket 没有相同的“每条连接”分派模型。官方文档说明 Accept 对数据报被忽略,由一个服务处理流量。不要试图用 Accept=yes 把 UDP 每个数据报变成一个独立服务实例。

变体:Unix socket 仍然需要匹配流式或数据报

若客户端与服务在同一台机器上,且程序使用 Unix 字节流,可以替换为路径式监听。下面的 SocketMode 约束文件节点访问模式,具体运行用户与目录安排还需结合服务部署设计。

# Unix 字节流变体:替换 [Socket] 段中的地址与类型。
[Socket]
ListenStream=/run/example-daemon/control.sock
SocketMode=0600
Accept=no

若程序实际使用 Unix 数据报,应改用 ListenDatagram 并保持双方类型一致。路径地址开头的斜线表示文件系统 Unix socket;抽象命名空间还有不同写法与生命周期,不要把文件节点权限规则直接套过去。

兼容坑:socket 已经存在,不等于服务会使用

systemd 可以创建监听端点并在有流量时激活服务,但程序必须接收传入描述符。原生接口通常通过 sd_listen_fds 读取管理器提供的描述符集合;程序应核对它们是否为自己支持的流式或数据报 socket,再使用对应的处理方式。

systemd持有监听socket并让服务进程读取传入描述符
Accept=no 下服务接管监听描述符的静态结构说明图。此图限定 Accept=no,管理器与服务共享对监听端点的访问关系,而不是服务再绑定相同地址。

如果服务启动后仍对同一地址执行普通 bind,可能报地址占用;如果它忽略描述符,也可能一直不消费已到达的数据。仅修改 ExecStart 或增加一个 socket unit 不能替不支持激活的程序实现接管。部署前应依据该程序的官方接口确认它采用原生传递还是 inetd 风格。

不要把描述符“从 3 开始”理解为永远只有一个 socket 且顺序固定。一个服务可能接收多个监听端点,多 socket unit 还会影响顺序约定。应检查类型及必要的识别信息,而不是在业务代码中固定把第一个当 TCP、第二个当 UDP。

完整片段:配套 service 只负责启动兼容程序

前面的 socket 文件名为 example-daemon.socket,Accept=no 下对应的普通服务文件可命名为 example-daemon.service:

# example-daemon.service:程序路径是占位,须替换为支持描述符接管的服务。
[Unit]
Description=Example socket-activated daemon

[Service]
Type=simple
ExecStart=/usr/local/libexec/example-daemon

/usr/local/libexec/example-daemon 是占位程序路径,不代表系统内置命令。必须替换为实际安装、且支持监听描述符接管的程序。不要直接使用这个不存在的路径启动服务,也不要自行添加未经该程序文档确认的“接管开关”。

这份骨架不需要把 service 自己启用成另一个独立的监听启动入口。由 socket 负责入口可以避免配置思路混乱;程序启动后的连接管理、数据报解析、错误处理仍属于服务实现。服务退出时也不应随意 unlink systemd 管理的 Unix socket 路径,或对 Accept=no 传入的共享监听 socket 调用 shutdown,影响管理器保留的监听端点。

常见问题

同一个端口数字能同时配置 TCP 和 UDP 吗

这是不同协议的端点,可以有相同端口数字,但程序必须确实支持两种协议并接管多个描述符。只为了“保险”同时配置两种监听,通常会增加歧义。

ListenStream 是否保留每次发送的消息边界

流式协议提供字节流,应用需要自己的消息分帧规则,例如长度前缀或明确分隔。不要把一次读取等同于客户端的一次发送。

选 ListenDatagram 就能避免消息丢失吗

不能。配置类型只说明数据报语义,不代替可靠传输、缓冲管理与业务确认。需要怎样的可靠性,应由具体协议与服务设计决定。

参考资料

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Python shared_memory.SharedMemoryManager 怎样批量清理共享段Python shared_memory.SharedMemoryManager 怎样批量清理共享段
上一篇
Python shared_memory.SharedMemoryManager 怎样批量清理共享段
Python concurrent.futures InterpreterPoolExecutor 适合什么任务
下一篇
Python concurrent.futures InterpreterPoolExecutor 适合什么任务
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    1019次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    1021次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1155次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1122次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    963次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码