通过 xinetd 的管理,可以按需启动某些“用完即走”的网络服务。实际上,xinetd 相当于网络层面的 wrapper, 应用程序只需要处理标准输入输出,网络层面的事情由 xinetd 代为处理即可。
以下是在 RHEL7 中实现的一个简单示例程序。
安装 xinetd 相关的包。
~]# yum install gcc xinetd telnet
编译一个 Hello world 标准输入输出程序。
tmp]# cat hello.c
#include <stdio.h>
int main()
{
char str[100];
printf("What's your name? \n");
scanf("%99s", str);
printf("Hello, %s\n", str);
return 0;
}
tmp]# gcc -Wall -o hello hello.c
#include <stdio.h>
int main()
{
char str[100];
printf("What's your name? \n");
scanf("%99s", str);
printf("Hello, %s\n", str);
return 0;
}
tmp]# gcc -Wall -o hello hello.c
在 xinetd 中添加相应的配置。在这个示例中,希望客户端访问 9991 端口时,能访问到 hello 这个程序。
~]# cat /etc/xinetd.d/hello-server service hello-server { protocol = tcp disable = no port = 9991 socket_type = stream wait = no user = root server = /tmp/hello } ~]# cat /etc/services | grep hello-server hello-server 9991/tcp # xinetd test
重启 xinetd 服务,可以看到 xinetd 服务会监听 9991 端口。
~]# systemctl restart xinetd ~]# ss -tulnp | grep 9991 tcp LISTEN 0 64 :::9991 :::* users:(("xinetd",pid=12855,fd=5))
通过 telnet 连接到 9991 端口,即可访问到 hello 程序。
~]# telnet 127.0.0.1 9991 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. feichashao What's your name? Hello, feichashao Connection closed by foreign host.
如果对 xinetd 进行 strace, 可以看到实际上 xinetd 是创建了一个 socket,在运行 hello 时将标准输入输出重定向到这个 socket 中。
12855 13:47:09.443422 setsockopt(6, SOL_IPV6, IPV6_ADDRFORM, [2], 4) = 0 <0.000010> 12902 13:47:09.449971 getpeername(6, {sa_family=AF_INET, sin_port=htons(52860), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 <0.000009> 12902 13:47:09.450013 getsockname(6, {sa_family=AF_INET, sin_port=htons(9991), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 <0.000007> 12902 13:47:09.450641 dup2(6, 0) = 0 <0.000008> 12902 13:47:09.450668 dup2(6, 1) = 1 <0.000007> 12902 13:47:09.450693 dup2(6, 2) = 2 <0.000007> 12902 13:47:09.450811 execve("/tmp/hello", ["hello"], ["LANG=en_US.UTF-8", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", "EXTRAOPTIONS=", "XINETD_LANG=en_US", "REMOTE_HOST=::ffff:127.0.0.1"]) = 0 <0.000157>