关于守护进程可以查看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. 【bzoj4589】Hard Nim FWT

    题目描述 Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下: 1. Claris和NanoApe两个人轮流拿石子,Claris先拿. 2. 每次只能从一堆中取若干个,可将一堆全取走, ...

  2. 适配IPhone X的技巧

    #define TabbarHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20?83:49) // ...

  3. BZOJ【1606】购买干草

    1606: [Usaco2008 Dec]Hay For Sale 购买干草 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 859  Solved: 63 ...

  4. 用.net开发wap

    原文发布时间为:2010-08-19 -- 来源于本人的百度文章 [由搬家工具导入] .NET 模板:http://download.csdn.net/source/2631001 WAP应用程序结构 ...

  5. DataRelation 实现父子表 父子级 Repeater的嵌套使用

    原文发布时间为:2009-05-21 -- 来源于本人的百度文章 [由搬家工具导入] DataRelation 实现父子表         if (!IsPostBack)        {      ...

  6. C++中的explicit关键字(转)

    按默认规定,只用传一个参数的构造函数也定义了一个隐式转换.举个例子: #pragma once class CExample { public: CExample(void); CExample(); ...

  7. Linux STP介绍

    1. 介绍 STP(Spanning Tree Protocol)即生成树协议,标准为IEEE802.1D-1998STP是一种二层冗余技术,利用STA算法构建一个逻辑上没有环路的树形网络拓扑结构,并 ...

  8. DNS+CDN

    参考: 一起学DNS系列文章:http://jeffyyko.blog.51cto.com/28563/186026 CDN技术原理:http://kb.cnblogs.com/page/121664 ...

  9. (一)python 简单网页爬虫

    1.基于window环境,使用的工具是 Anaconda 下载地址 https://www.anaconda.com/download/ 2.所使用的包 BeautifulSoup,用来解析html代 ...

  10. (11)centos之vim使用

    ZZ 保存并退出 :x 保存并退出 :q 不保存退出