使用systemd <service>.socket时,套接字对应的文件描述符是多少?
systemd.socket(Accept=no)文件描述符规则说明
Accept=no场景下的套接字传递逻辑和Accept=yes的inetd模式完全不同,不会修改0(标准输入)、1(标准输出)、2(标准错误)三个标准流的指向,所有监听套接字的文件描述符固定从3开始按配置顺序递增分配。
具体规则和区分方案:
- 编号分配逻辑:文件描述符的顺序和你在
.socket配置文件中写的ListenXXX配置项的先后顺序完全对应。第一个Listen配置对应fd=3,第二个对应fd=4,以此类推,不会占用标准流的fd编号。 - 区分不同套接字的两种方案:
- 顺序匹配:如果你的套接字配置不会频繁调整,直接按配置的先后顺序对应fd编号即可。比如你示例中先写
ListenDatagram再写ListenFIFO,程序里fd=3就是数据报套接字,fd=4就是FIFO的文件描述符。 - 自定义名称匹配:如果怕配置顺序变动导致业务出错,可以给每个
Listen项配置独立名称,在对应ListenXXX配置的上方添加FileDescriptorName=自定义标识配置,程序启动时通过对应系统接口即可获取每个fd关联的自定义名称,按名称匹配即可,示例配置如下:[Socket] FileDescriptorName=datagram_listen ListenDatagram=/run/<service>/listen.sock FileDescriptorName=ipc_fifo ListenFIFO=/run/<service>/IPC.FIFO Accept=no
- 顺序匹配:如果你的套接字配置不会频繁调整,直接按配置的先后顺序对应fd编号即可。比如你示例中先写
- 额外注意项:systemd会给服务进程自动注入
LISTEN_FDS环境变量,值为传递的套接字总数量,程序启动时可以先读取该变量确认收到的fd总数,避免硬编码数量导致越界错误。所有传递过来的fd已经完成了bind、listen操作,程序不需要重复执行这些步骤,直接处理连接或读写即可。
内容的提问来源于stack exchange,提问作者Alexis Wilke
相关产品推荐
相关产品推荐

