UNIX网络编程---守护进程和inetd超级服务器
守护进程是在后台运行且不于任何控制终端挂链的进程。UNIX系统有很多守护进程在后台工作(有20到50的数量级),执行不同的任务。守护进程没有控制终端通常源于它们由系统初始化脚本启动。然而守护进程也可能从某个终端由用户在shell提示符下键入命令行启动,这样的守护进程必须亲自脱离于控制终端的关联,从而避免与作业的控制、终端会话管理、终端产生信号等发生任何不期望的交互,也可以避免在后台运行的守护进程非预期低输出到终端。
守护进程有多重启动方法:
1) 在系统启动阶段,由系统初始化脚本启动
2) 有inetd超级服务器启动,inetd自身由上一条中的某个脚本启动。inetd监听网络请求,每当有一个请求到达时,启动相应的实际服务器。
3) Cron守护进程按照规则定期执行一些程序,而由它启动执行的程序同样作为守护进程运行。其自身由某个脚本启动。
4) at命令用于指定将来某个时刻的程序执行。这些程序的执行时刻到来时,通常有cron守护进程启动执行他们,因此这些程序同样作为守护进程运行。
5) 守护进程还可以行用户终端或在前台或在后台启动。这么做往往是为了测试守护程序或重启因某种原因而终止了的某个守护进程。
此守护进程通常由某个系统初始化脚本启动
1) 读取配置文件。通常为/etc/syslog.conf的配置文件指定本守护进程可能收取的各种日志消息应该如何处理。这些消息坑内被添加到一个文件/dev/console文件时一个特例,它把消息写到控制台上),或被写到指定用户的登录窗口,或被转发给另一个主机上的syslogd进程。
2) 创建一个UNIX域数据报套接字,给它捆绑路径名/var/run/log(有的是/dev/log)
3) 创建一个udp套接字,给他捆绑端口514(syslog服务使用的端口号)。
4) 打开路径名/dev/klog、来自内核中的任何出错消息看着像是这个设备的输入
此后syslogd守护进程在一个无限循环中进行,调用select以等到它的三个描述符(来自上述第2、3、4步)之一变为可读,读取日志消息,并按照配置文件进行处理。如果守护进程收到SIGHUP信号,那就是重新读取配置文件。
通过创建一个UNIX域数据报套接字,我们就可以从自己的守护进程中通过syslogd绑定的路径名发送我们的消息达到发送日志消息的目的。
从守护进程中等级消息的常用技巧就是调用syslog函数
#include<syslog.h>
Void syslog(intpriority,const char *message,…..);
函数中的priority参数是级别和设施两者的组合,message参数类似printf的格式串,日志信息的level从0到7,按照东高到低的顺序排列的,默认情况为LOG_NOTICE
举例来说,当rename函数调用意外失败时,守护进程可以执行以下调用
Syslog(LOG_INFO|LOG_LOCAL2,”RENAME(%S,%S):%m”,file1,file2);
当syslog被应用进程首次调用时,它闯将一个UNIX域数据报套接字,然后调用connect连接到有syslogd守护进程创建的UNIX域数据报套接字的周所周知的路径名(譬如/var/run/log)
这个套接字一直保持打开,直到进程终止为止。进程也可以使用openlog和closelog
#include <syslog.h>
Void openlog(const char *ident,intoptions,int facility);
Void closelog(void);
Openlog可以在首次调用syslog前调用,closelog可以在应用进程不再需要发送日志消息时调用
Ident参数是一个有syslog冠于每个日志消息之前的字符串。它的值通常是程序名
Openlog被调用时,通常并不立即创建UNIX域套接字。该套接字直到首次调用syslog时才打开。LOG_NDELAD选项破事该套接字在openlog被调用时就创建。
调用这个函数可以把普通进程转换为守护进程。但是在有的UNIX变体中已经更改了使用方法
在TFTP、telnet/tftp这些服务来说,都会有一个进程与之关联。每个进程执行几乎相同的任务:创建一个套接字,把本地服务器的周所周知端口捆绑到该套接字,等待一个连接或一个数据报,然后派生子进程。子进程为客户提供服务,父进程则继续等到下一个客户请求
1) 所有这些守护进程含有几乎相同的启动代码,既表现在创建套接字上,也表现在演变成守护进程上。
2) 每个守护进程在进程表中占据一个表项,然而它们大部分时间处于睡眠状态,因特网超级服务器(既inetd守护进程)使上述问题得到简化。基于TCP或UDP的服务器都可以使用这个守护进程
这个函数是自己编写的函数,代码很简单,在实际过程中基本不用
PS:
守护进程是在后台运行并独立于所有终端控制的进程。许多网络服务器作为守护进程运行。守护进程产生的所有输出通常通过调用syslog函数发生给syslogd守护进程。系统管理员可根据发送消息的守护进程以及消息的严重级别,完全控制这些消息的处理方式。
启动任意一个程序并让它作为守护进程运行需要以下步骤:调用fork以转到后台运行,调用setsid建立一个新的POSIX会话并成为会话头进程,再次fork以避免无意中获得新的控制终端,改变工作目录和文件创建模式掩码,最后关闭所有非必要的描述符,daemon_init函数处理所有这些细节‘
许多UNIX服务器有inetd守护进程启动,它处理全部守护进程化所需的步骤,当启动真正的服务器时,套接字已在标准输入、标准输出和标准错误输出上打开。这样我们无需调用socket、bind、listen和accept,因为这些步骤已有inetd处理。