UNP学习笔记(第十三章 守护进程和inetd超级服务器)
关于守护进程可以查看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超级服务器)的更多相关文章
- Unix网络编程代码 第13章 守护进程和inetd超级服务器
1. 概述 守护进程是在后台运行且不与任何控制终端关联的进程.unix系统通常有很多守护进程在后台运行,执行不同的管理任务. 守护进程没有控制终端通常源于它们由系统初始化脚本启动.然而守护进程也 ...
- 《APUE》读书笔记第十三章-守护进程
守护进程 守护进程是生存期较长的一种进程,它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNIX系统由很多守护进程,它们执行日常事务活动. 本章主要介 ...
- UNP学习第13章 守护进程和inetd超级服务器
Unix系统中的syslogd守护进程通常由某个系统初始化脚本启动,而且在系统工作期间一直运行. 源自Berkeley的syslogd实现在启动时执行以下步骤. (1)读取配置文件.通常为/etc/s ...
- 《Unix 网络编程》13:守护进程和 inetd 超级服务器
守护进程和 inetd 超级服务器 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...
- APUE读书笔记-第13章-守护进程
第13章 守护进程 13.1 引言 *守护进程也称精灵进程(daemon)是生存期较长的一种进程.它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNI ...
- 守护进程和inetd超级服务器
守护进程: 1 系统启动时,由系统初始化脚本启动.一般在/etc目录下,或者以/etc/rc开头的目录 2 许多网络服务器由inetd超级服务器启动 3 cron守护进程按规则定期执行一些程序 4 用 ...
- apue学习笔记(第十三章 守护进程)
本章将说明守护进程结构,以及如何编写守护进程程序. 守护进程,也就是通常说的Daemon进程,是Unix中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理 ...
- 《Unix环境高级编程》读书笔记 第13章-守护进程
1. 引言 守护进程是生存期长的一种进程.它们常常在系统引导装入时启动,仅在系统关闭时才终止.它们没有控制终端,在后台运行. 本章说明守护进程结构.如何编写守护进程程序.守护进程如何报告出错情况. 2 ...
- Linux学习笔记(9)-守护进程
明天学这个!! ---------------------------------------------------------- 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终 ...
随机推荐
- 理解点击屏幕的事件响应--->对- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event方法的理解
要理解这两个方法.先了解一下用户触摸屏幕后的事件传递过程. 当用户点击屏幕后,UIApplication 先响应事件,然后传递给UIWindow.如果window可以响应.就开始遍历window的su ...
- 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra
题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个 ...
- 【bzoj4966】总统选举 随机化+线段树
题目描述 黑恶势力的反攻计划被小C成功摧毁,黑恶势力只好投降.秋之国的人民解放了,举国欢庆.此时,原秋之国总统因没能守护好国土,申请辞职,并请秋之国人民的大救星小C钦定下一任.作为一名民主人士,小C决 ...
- 【CCF】JSON查询
#include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...
- Chrome扩展修改页面代码执行环境的方法
Chrome的扩展程序可以通过content scripts向页面中注入js代码,所注入的js代码能够对页面中所有的DOM对象进行操作.由于Chrome在js执行环境上对页面代码和content sc ...
- [SaltStack] salt-master启动流程
SaltStack源码阅读 做salt有一段时间了, 一直没从源码层面去理解, 好吧, 开始读读源码 -_- 那就从salt-master的启动开始吧. 启动salt-master方法: /etc/i ...
- UnionFind(PYthon实现)
UnionFind用于解决图的连通性问题,不需要给出具体路径的情况,可用来计算连通分支数 参考链接: https://blog.csdn.net/dm_vincent/article/details/ ...
- UVALive 6514:Crusher’s Code(概率dp)
题目链接 https://icpcarchive.ecs.baylor.edu/external/65/6514.pdf 题意:给出n个数(n<8) 求这n个数分别两个程序排成有序时,程序的期望 ...
- poj 3321(树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24954 Accepted: 7447 Descr ...
- hdu 1595(最短路变形好题)
find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others) Memory Limit: 32768/32768 ...