守护进程

来源:互联网 发布:mac电脑的终端命令 编辑:程序博客网 时间:2024/05/01 12:14

UNIX操作系统为用户提供inetd daemon 进行网络服务管理。它将所有的后台应用程序置于它的管理之下,在客户端没有请求时,所有的后台应用程序都不启动,一旦客户端有特定的请求上来,它将根据/etc/services 和/etc/inetd.conf 文件描述的请求端口号和服务名调动相应的应用程序进行处理,而其它后台应用程序是不启动的。被启动的应用程序完成了特定任务后就终结自己的进程,这就减轻了系统负载,节约了系统资源,极大地提高了系统效率,是实现应用系统网络互连的一个实用工具。 
inetd daemon 在开机时由/etc/rc.tcpip文件启动,一旦inetd daemon 启动即从 /etc/inetd.conf 文件中读取它的配置信息,然后在特定的套接字上监听连接请求,该文件的作用是告诉 inetd daemon 各端口号上的请求如何处理。即该服务采用何种套接字类型,是字节流还是数据报,采用什么协议(TCP/UDP),应用程序等待否,在监听套接字之前是否释放套接字,应用程序的名字、参数及路径等。

 

下面是守护进程实例

 

时间服务器:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <syslog.h>#include <signal.h>#include <time.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#define MAXFD64#define MAXLINE255//extern int daemon_proc;void daemon_init(const char *pname, int facility){int i = 0;pid_t pid;if ((pid = fork()) != 0)//创建第一个子进程{exit(0);//父进程结束}//第一个子进程继续setsid();//成为会话头signal(SIGHUP, SIG_IGN);//忽略SIGHUP信号if ((pid = fork()) != 0){exit(0);//第一个子进程结束}//daemon_proc = 1;//第二个子进程继续chdir("/");//改变工作目录umask(0); //清除文件模式创建掩码for (i=0; i<MAXFD; i++){close(i);}open( "/dev/null", O_RDONLY);open( "/dev/null", O_RDWR);open( "/dev/null", O_RDWR);openlog(pname, LOG_PID, facility);//用syslogd处理错误}int main(int argc, char **argv){int listenfd, connfd;socklen_t addrlen, len;struct sockaddr cliaddr;struct sockaddr_in server;char buff[MAXLINE];time_t ticks;(void)addrlen;bzero(&cliaddr, sizeof(cliaddr));bzero(&server, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(1234);server.sin_addr.s_addr = htonl(INADDR_ANY);daemon_init(argv[0], 0);listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd < 0){syslog(LOG_NOTICE|LOG_LOCAL0, "socket error");return -1;}if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) < 0){syslog(LOG_NOTICE|LOG_LOCAL0, "bind error");return -1;}if (listen(listenfd, 5) < 0){return -1;}for (;;){len = sizeof(cliaddr);connfd = accept(listenfd, &cliaddr, &len);if (connfd < 0){syslog(LOG_NOTICE|LOG_LOCAL0, "accept error");return -1;}ticks = time(NULL);snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));if (write(connfd, buff, strlen(buff)) < 0){syslog(LOG_NOTICE|LOG_LOCAL0, "write error");return -1;}close(connfd);}close(listenfd);return 1;}


客户端程序:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#define PORT1234#define MAXSIZE 1024int main(int argc, char **argv){int sockfd;struct sockaddr_in serverSock;int num = 0;char buff[MAXSIZE] = {0};struct hostent *he;if (argc != 2){printf("Usage: %s <IP Address>\n", argv[0]);return -1;}he = gethostbyname(argv[1]);if (he == NULL){printf("gethostbyname fails!\n");return -1;}sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){printf("Create socket fails!\n");return -1;}bzero(&serverSock, sizeof serverSock);serverSock.sin_family = AF_INET;serverSock.sin_port = htons(PORT);serverSock.sin_addr = *((struct in_addr *)he->h_addr);if (connect(sockfd, (struct sockaddr *)&serverSock, sizeof serverSock) < 0){printf("connect fails!\n");return -1;}num = recv(sockfd, buff, MAXSIZE, 0);if (num < 0){printf("recv message fails!\n");return -1;}buff[num-1] = '\0';printf("%s\n", buff);close(sockfd);return 1;}

编译后,运行服务器程序,用ps -axu命令就能找到刚运行的守护进程。从显示的结果中可以看到,其中tty项为?的就表示为守护进程。

原创粉丝点击