我们不难发现,前两章的例子有一个共同点:他们同时只能为一个单一客户端服务,但这样做导致我们的机器被大多数空闲的进程消耗掉大量内存,这是不符合实际的。我们有很多方法可以解决这个问题,一个方法使使用内部方法来处理多客户端(具体如何实现后续章节将进行介绍),另一个方法使每次有新客户端连接的时候,就启用一个服务器拷贝。
UNIX和类UNIX操作系统提供了一个叫做inted或xinetd的程序来解决这个问题。
注意:由于微软并没有随Windows捆绑任何inetd程序,本章节内容并不适用于Windows平台,若读者感兴趣,可自行安装Unix或Linux环境(虚拟机)对本章代码进行测试。
3.1 inetd/xinetd简介
inetd和xinetd都是Unix/Linux系统上的守护进程,用于管理网络服务。将inetd/xinetd程序打开,绑定、监听和接受来自服务器每一个端口的请求。当有客户端连接的时候,inted/xinted会根据客户端信息到达的端口号判断请求的是哪一个服务,接着inetd/xinetd会调用服务器程序并把socket传给它。
inetd(Internet service daemon)是最早的网络服务管理器,它在系统启动时启动并监听指定的网络端口。当有连接请求到达时,inetd会根据配置文件(通常是/etc/inetd.conf)启动相应的服务程序来处理连接。
xinetd(Extended Internet service daemon)是inetd的增强版,它提供了更多的功能和配置选项。xinetd在inetd的基础上增加了许多功能,包括访问控制、资源限制、日志记录等。xinetd的配置文件通常位于/etc/xinetd.conf或/etc/xinetd.d/目录下。我们接下来主要介绍xinetd服务的配置及相关应用。
3.2 配置xinetd
3.2.1 xinetd的基本服务选项
选项名称 | 描述 | 用法示例 |
---|---|---|
service | 定义一个服务的开始,通常包括服务的名称和协议类型 | service echo {...} |
socket_type | 定义套接字类型,可以是 stream(流套接字,如 TCP)或 dgram(数据报套接字,如 UDP) | socket_type = stream |
type | 服务类型,通常是 UNLISTED 或 INTERNAL。使用UNLISTED定义一个不再/etc/services列表上,而是在 xinetd 的配置文件中直接定义的服务。 | type = UNLISTED |
flag | 特殊标记,例如 REUSE 允许重用套接字 | flag=REUSE |
port | 如果设置了type = UNLISTED,必须再指定端口号 | port=12345 |
protocol | 定义使用的协议,可以是 tcp 或 udp | protocol = tcp |
wait | 指定服务是否等待(等待客户端连接关闭前不接受新连接)。对于 dgram 服务,通常设置为 yes;对于 stream 服务,设置为 no | wait = no |
user | 指定运行服务的用户。 | user = nobody |
group | 指定运行服务的用户组。 | group = nogroup |
server | 指定提供服务的可执行文件路径 | server = /usr/sbin/in.telnetd |
server_args | 指定传递给服务器程序的参数。 | server_args = -L /bin/login |
log_type | 指定日志记录的类型,可以是 SYSLOG 或 FILE。 | log_type = SYSLOG daemon info |
log_on_success | 指定记录成功连接的日志信息,包括 PID, HOST, USERID 等。 | log_on_success = HOST PID |
log_on_failure | 指定记录失败连接的日志信息。 | log_on_failure = HOST |
disale | 可以设置为 yes 或 no 来表示是否禁用该服务。 | disable = no |
onlyfrom | 只允许特定主机访问服务。 | only_from = 192.168.0.0/24 |
no_access | 拒绝特定主机访问服务。 | no_access = 192.168.0.5 |