我喜欢在开发过程中使用systemd-activate(8)
测试套接字激活的守护进程,
但是,它似乎只侦听TCP连接:
% /usr/lib/systemd/systemd-activate -l 5700 ./prog
Listening on [::]:5700 as 3.
% netstat -nl |grep 5700
tcp6 0 0 :::5700 :::* LISTEN
我正在使用处理数据报(UDP)的程序。如何让systemd-activate
监听UDP端口?还是有一个
使用其他工具执行此操作的简单方法,而不会遇到制作和安装systemd单元文件的麻烦?
答案 0 :(得分:1)
最近已添加到systemd-activate
:https://github.com/systemd/systemd/pull/2411,并且在发布时将成为systemd-229的一部分。
答案 1 :(得分:0)
我不确定是否有办法systemd-activate
。
您可能希望使用一些.service
单元文件和一个带有依赖项的.socket
单元文件。在.socket
单元中,您将描述ListenDatagram=
选项。有关详细信息,请参阅here。
答案 2 :(得分:0)
我最终写了一个简单的C程序来做这件事;下面的代码(公共领域)。
用法是:
./a.out <port-number> <prog> [<arg1> ...]
程序在<port-number>
上打开一个UDP套接字,设置系统套接字激活的守护进程所期望的环境变量,然后用随后的参数执行<prog>
。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
int main(int argc, char **argv) {
if (argc < 2) {
printf("no port specified\n");
return -1;
}
if (argc < 3) {
printf("no program specified\n");
return -1;
}
uint16_t port = htons((uint16_t) strtoul(argv[1], NULL, 10));
if (port == 0 || errno) {
printf("failed to parse port: %s\n", argv[1]);
return -1;
}
/* create datagram socket */
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
printf("failed to open socket; errno: %d\n", errno);
return -1;
}
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = port;
sa.sin_addr.s_addr = INADDR_ANY;
/* bind socket to port */
int r = bind(fd, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
if (r < 0) {
printf("bind failed; errno: %d\n", errno);
return -1;
}
/* execute subprocess */
setenv("LISTEN_FDS", "1", 0);
execvp(argv[2], argv + 2);
}