关于守护进程可以查看apue的笔记 http://www.cnblogs.com/runnyu/p/4645046.html

daemon_init函数

下面给出名为daemon_init函数,通过调用它(通常从服务器程序中),我们能够把一个普通进程转变为守护进程

 #include    "unp.h"
#include <syslog.h> #define MAXFD 64 extern int daemon_proc; /* defined in error.c */ int
daemon_init(const char *pname, int facility)
{
int i;
pid_t pid; if ( (pid = Fork()) < )
return (-);
else if (pid)
_exit(); /* parent terminates */ /* child 1 continues... */ if (setsid() < ) /* become session leader */
return (-); Signal(SIGHUP, SIG_IGN);
if ( (pid = Fork()) < )
return (-);
else if (pid)
_exit(); /* child 1 terminates */ /* child 2 continues... */ daemon_proc = ; /* for err_XXX() functions */ chdir("/"); /* change working directory */ /* close off file descriptors */
for (i = ; i < MAXFD; i++)
close(i); /* redirect stdin, stdout, and stderr to /dev/null */
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR); openlog(pname, LOG_PID, facility); return (); /* success */
}

作为守护进程运行的时间获取服务器程序

 #include    "unp.h"
#include <time.h> int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t addrlen, len;
struct sockaddr *cliaddr;
char buff[MAXLINE];
time_t ticks; if (argc < || argc > )
err_quit("usage: daytimetcpsrv2 [ <host> ] <service or port>"); daemon_init(argv[], ); if (argc == )
listenfd = Tcp_listen(NULL, argv[], &addrlen);
else
listenfd = Tcp_listen(argv[], argv[], &addrlen); cliaddr = Malloc(addrlen); for ( ; ; ) {
len = addrlen;
connfd = Accept(listenfd, cliaddr, &len);
err_msg("connection from %s", Sock_ntop(cliaddr, len)); ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff)); Close(connfd);
}
}

inetd守护进程

典型的UNIX系统可能存在许多服务器,它们只是等待客户请求的到达,例如:FTP、Telnet、Rlogin、TFTP等等。

在之前,所有这些服务都有一个进程与之关联,而且每个进程执行几乎相同的启动任务。这个模型存在以下两个问题:

1.所有这些守护进程含有几乎相同的启动代码。

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

4.3BSD版本基于TCP或UDP的服务器都可以使用inetd守护进程来解决上述两个问题:

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

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

inetd进程使用我们随daemon_init函数讲解的技巧把自己演变成一个守护进程。

接着读入并处理自己的配置文件。通常是/etc/inetd.conf的配置文件制定本超级服务器处理哪些服务以及当一个服务请求到达时该怎么做。该文件中每行包含的字段如下图所示:

下面是inetd.conf文件中作为例子的若干行:

下面展示inetd守护进程的工作流程

1.在启动阶段,读入/etc/inetd.conf文件并给该文件中指定的每个服务创建一个适当类型的套接字。新创建的每个套接字都被加入到将由某个select调用使用的一个描述符。

2.位每个套接字调用bind,指定捆绑相应服务器的总所周知的端口和通配地址。端口号通过getservbyname获得。

3.对于每个TCP套接字,调用listen以接收外来的连接请求。对于UDP套接字则不执行该步骤。

4.创建完毕所有套接字之后,调用select等待其中任何一个套接字变为可读。

5.当select返回指出某个套接字可读之后,如果该套接字时一个TCP套接字,而且其服务器的wait-flag值为nowait,那么调用accept接受这个新连接。

6.inetd守护进程调用fork派生进程,并由子进程处理服务请求。(子进程首先与终端脱离,然后调用exec执行相应的server-program字段指定的程序来具体处理请求)

7.如果第五步中select返回的是一个字节流套接字,那么父进程必须关闭已连接套接字(就像标准并发服务器那样)。父进程再次调用select,等待下一个变为可读的套接字。

daemon_inetd函数

下面给出一个名为daemon_inetd的函数,可用于已知由inetd启动的服务器程序中。

 #include    "unp.h"
#include <syslog.h> extern int daemon_proc; /* defined in error.c */ void
daemon_inetd(const char *pname, int facility)
{
daemon_proc = ; /* for our err_XXX() functions */
openlog(pname, LOG_PID, facility);
}

与daemon_init相比,所有的守护进程化步骤已由inetd在启动时执行。本函数的任务仅仅是为错误处理函数设置daemon_proc标志,并调用openlog

下面给出由inetd作为守护进程启动的时间获取服务器程序

 #include    "unp.h"
#include <time.h> int
main(int argc, char **argv)
{
socklen_t len;
struct sockaddr *cliaddr;
char buff[MAXLINE];
time_t ticks; daemon_inetd(argv[], ); cliaddr = Malloc(sizeof(struct sockaddr_storage));
len = sizeof(struct sockaddr_storage);
Getpeername(, cliaddr, &len);
err_msg("connection from %s", Sock_ntop(cliaddr, len)); ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(, buff, strlen(buff)); Close(); /* close TCP connection */
exit();
}

可以看到,所有套接字创建代码都消失了。这些步骤改由inetd执行。

为了运行本例子的程序,我们首先赋予本服务一个名字和端口,将如下行加到/etc/services文件中:

mydaytime     /tcp

接着把如下行加到/etc/inetd.conf文件中:

mydaytime stream tcp nowait andy /home/andy/daytimetcpsrv3 daytimetcpsrv3

然后给inetd发送一个SIGHUP信号,告知它重新读入其配置文件。

接着我们执行netstat命令验证inetd已在TCP端口9999上创建一个监听套接字

UNP学习笔记(第十三章 守护进程和inetd超级服务器)的更多相关文章

  1. Unix网络编程代码 第13章 守护进程和inetd超级服务器

    1. 概述 守护进程是在后台运行且不与任何控制终端关联的进程.unix系统通常有很多守护进程在后台运行,执行不同的管理任务.    守护进程没有控制终端通常源于它们由系统初始化脚本启动.然而守护进程也 ...

  2. 《APUE》读书笔记第十三章-守护进程

    守护进程 守护进程是生存期较长的一种进程,它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNIX系统由很多守护进程,它们执行日常事务活动. 本章主要介 ...

  3. UNP学习第13章 守护进程和inetd超级服务器

    Unix系统中的syslogd守护进程通常由某个系统初始化脚本启动,而且在系统工作期间一直运行. 源自Berkeley的syslogd实现在启动时执行以下步骤. (1)读取配置文件.通常为/etc/s ...

  4. 《Unix 网络编程》13:守护进程和 inetd 超级服务器

    守护进程和 inetd 超级服务器 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...

  5. APUE读书笔记-第13章-守护进程

    第13章 守护进程 13.1 引言 *守护进程也称精灵进程(daemon)是生存期较长的一种进程.它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNI ...

  6. 守护进程和inetd超级服务器

    守护进程: 1 系统启动时,由系统初始化脚本启动.一般在/etc目录下,或者以/etc/rc开头的目录 2 许多网络服务器由inetd超级服务器启动 3 cron守护进程按规则定期执行一些程序 4 用 ...

  7. apue学习笔记(第十三章 守护进程)

    本章将说明守护进程结构,以及如何编写守护进程程序. 守护进程,也就是通常说的Daemon进程,是Unix中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理 ...

  8. 《Unix环境高级编程》读书笔记 第13章-守护进程

    1. 引言 守护进程是生存期长的一种进程.它们常常在系统引导装入时启动,仅在系统关闭时才终止.它们没有控制终端,在后台运行. 本章说明守护进程结构.如何编写守护进程程序.守护进程如何报告出错情况. 2 ...

  9. Linux学习笔记(9)-守护进程

    明天学这个!! ---------------------------------------------------------- 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终 ...

随机推荐

  1. mysql再次安装问题

    安装过一次mysql的电脑,想再安装或更换其它版本的mysql.在重新安装的最后一步,总会出现这样的问题. 网上说法也很多,什么删除注册表了等等.这都是狗屁. 真正的做法是找到C盘下的隐藏文件夹Pro ...

  2. [JSOI2007]建筑抢修 (贪心)

    题目链接 Solution 可以考虑 \(dp\) ,但是很显然 \((n^2)\) 降不下来. 然后考虑贪心,首先,绝对的正确的是,在同等的情况下,给后面的留更多的时间. 首先按照 \(T_2\) ...

  3. hdu 1503 最长公共子序列

    /* 给两个串a,b.输出一个最短的串(含等于a的子序列且含等于b的子序列) */ #include <iostream> #include <cstdio> #include ...

  4. Bzoj2829 信用卡凸包

    Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 333  Solved: 155 Description Input ...

  5. dva脚手架 dva-cli 配置roadhogrc,antd-mobile样式按需加载 不生效的问题

    1.新安装dva-cli脚手架版本0.9.2,dva版本是2.4.1,roadhogrc版本是2.4.9 roadhogrc2 与1 的区别把roadhogrc 改成了webpackrc 所以配置an ...

  6. Win7下VS2010、IIS7配置常见问题收集

    一 在Win7下应按什么次序安装vs2010和iis7 win7推荐先安装iis7,再安装vs2010:如果次序反了,必须注册iis才可以用. IIS中ASP.NET的版本号此时可选的有1.1.2.0 ...

  7. AC日记——[HAOI2007]理想的正方形 P2216

    [HAOI2007] 理想的正方形 思路: 正解多个单调队列: 但是我用树套树水了过去: 来,上代码: #include <cstdio> #include <cstring> ...

  8. 强连通分量(Tarjan)模板

    贴模板,备忘. 模板1: #include<iostream> #include<cstring> #include<cmath> #include<cstd ...

  9. Mysql varchar长度问题

    http://dinglin.iteye.com/blog/914276 http://www.cnblogs.com/fakis/archive/2011/03/07/1976532.html   ...

  10. koa2 从入门到进阶之路 (三)

    之前的文章我们介绍了一下 koa 路由,get 传值,动态路由,本节我们看一下 koa 中间件 以及 koa 中间件的洋葱图执行流程. 一.什么是 Koa 的中间件 通俗的讲:中间件就是匹配路由之前或 ...