Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239313
  • 博文数量: 131
  • 博客积分: 259
  • 博客等级: 二等列兵
  • 技术积分: 705
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-21 21:15
文章分类

全部博文(131)

文章存档

2013年(3)

2011年(128)

分类:

2011-03-16 19:26:20

原文地址:inetd超级服务器 作者:zyd_cu

xinetdinetd超级服务器的升级版,相当于inetd + tcp wrapper,将服务管理与访问控制结合在一起。在介绍inetd之前,先看一个xinetd的实例(我的机器上只有xinetd,关于inetd的配置参考UNP 325页)。

 

xinet配置实例

xinetd添加myecho服务(将客户端发来的请求消息回送给客户端)。

1. /etc/services中添加myecho服务的信息。

myecho  12580/tcp

2. 编写服务器程序,并生成可执行文件/root/echo

#include

int main()

{

int n;

char buf[4096];

n = read(0, buf, 4096);

write(1, buf, n);

return 0;

}

3. 增加myechoxinetd配置项,创建文件/etc/xinetd.d/myecho

    service myecho

{

        socket_type = stream

        protocol        = tcp

        wait            = no

        user            = root

        server          = /media/sf_desktop/echo

}

4. 重启xinetd或向xinet发送SIGHUP信号,使其重新加载配置文件

    /etc/init.d/xinetd restart  或者

    ps aux | grep xinetd 获取xinetd的进程号xid

    kill –SIGHUP xid

    通过netstat –an | grep 12580查看xinet启动了myecho服务。

5.编写简单客户端程序访问myecho服务器进行测试。

 

为什么需要inetd

典型的unix系统可能存在许多服务器,它们只是等待客户请求的到达,如FTPTelnetRloginTFTP等。最开始,所有的这些服务都与一个进程相关联,这些进程在系统启动时开始运行,而且执行几乎相同的启动任务:创建一个套接口,把本服务的众所周知的端口捆绑到该套接口,等待一个连接(TCP)或是一个数据报(UDP),然后派生子进程。子进程为客户提供服务,父进程则等待下一个客户请求。这个模型存在两个问题:

1.  所有这些守护进程含有几乎相同的启动代码(套接口的创建以及成为守护进程)。

2.  每个守护进程在进程表中占据一项,并且大部分时间处于睡眠状态。

 

inetd超级服务器使上述的问题得到简化:

1. 通过inetd处理普通进程的大部分细节以简化守护程序的编写。

2. 单个进程(inetd)就能为多个服务等待外来的客户请求,以此取代每个服务一个进程的做法,减少了系统中的进程数。

 

inetd的工作原理

inetd守护进程的工作流程(如下图所示)

1. 在启动阶段,读入配置文件(/etc/inetd.conf /etc/xinetd.conf),对于配置文件中的每个服务创建一个适当类型(TCPUDP)的套接口。新创建的每个套接口都被加入到将由某个select调用使用的一个描述字集中。、

xinetd(inetd)的配置文件中包含服务的类型(如上例中的streamtcp),服务模式(如上例中的nowait),服务程序(如上例中的/root/echo)以及访问控制信息、日志等信息。

2. 为每个套接口调用bind(根据/etc/services中的配置项)。

3. 对于每个TCP套接口,调用listen以接受外来的连接请求;

4. 创建完毕所有套接口后,调用select等待其中任何一个套接口变为可读。inetd的大部分时间阻塞于select调用内部,等待某个套接口变为可读。

5. select返回指出某个套接口可读以后,如果该套接口是TCP套接口,而且其服务器为nowait类型,则调用accept接受这个连接。

6. inetd调用fork派生进程,并由子进程处理服务请求。

l  子进程关闭要处理的套接口描述字之外的所有描述字(对于TCPaccept返回的套接口,对于UDP为最初创建的套接口),子进程三次调用dup2,把待处理套接口的描述字复制到描述字012上;然后关闭原套接口描述字。因此,子进程打开的描述字只有012。子进程从标准输入读,相当于从所处理的套接口读;子进程往标准输出或标准错误上写,相当于往所处理套接口写。

l  子进程根据login-name(user)的配置值,如果不是root,子进程则调用setgidsetuid把自身改为指定的用户。

l  子进程调用exec执行由配置文件指定的程序( 如上例中的/root/echo)来具体处理请求。

7. 如果5中返回的是TCP套接口,则父进程先关闭接受请求产生的连接套接口。父进程在此调用select,等待下一个变为可读的套接口。

 

 

inetd不是万能的

inetd通常不适合提供大量密集服务的服务器,如mail服务以及web服务,因为inetd对每次请求都执行一次fork+exec,对于频繁的数据请求来说,开销相当大。Web服务器使用各种技术(如多线程等)尽量将每个连接处理的开销降到最小。

 

阅读(397) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~