1 #include <stdio.h> 2 #include <errno.h> 3 #include <signal.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <unistd.h> 8 #include <sys/param.h> 9 #include <sys/resource.h> 10 #include <sys/types.h> /* basic system data types */ 11 #include <sys/socket.h> /* basic socket definitions */ 12 #include <sys/time.h> /* timeval{} for select() */ 13 #include <time.h> /* timespec{} for pselect() */ 14 #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */ 15 #include <arpa/inet.h> /* inet(3) functions */ 16 #include <fcntl.h> /* for nonblocking */ 17 #include <netdb.h> 18 #include <sys/stat.h> /* for S_xxx file mode constants */ 19 #include <sys/uio.h> /* for iovec{} and readv/writev */ 20 #include <sys/wait.h> 21 #include <sys/un.h> /* for Unix domain sockets */ 22 23 #define BUF_SIZE 8192 24 #define LISTENQ 1024 25 26 /************* 27 * 要实现的任务 28 * 1. 将调用的函数初始化为守护进程 29 * 2. 建立tcp的server等待连接 30 * 3. 在并发中调用一个reveive_xml函数去执行保存 31 * 4. 处理一些信号问题 32 * 33 * 34 * 35 *********************/ 36 int daemon_init(void) 37 { 38 int i, fd0, fd1, fd2; 39 pid_t pid; 40 struct rlimit rl; 41 struct sigaction sa; 42 43 umask(0);//第一步用umask将文件创建屏蔽字设置为一个已知的值 44 45 46 if ((pid = fork()) < 0)//第二步调用fork,然后使父进程exit(会话周期和进程组和终端控制没改变) 47 exit(1); 48 else if (pid != 0) /* parent */ 49 exit(0); 50 51 setsid();//第三步调用setsid创建一个新的会话(让进程摆脱原会话,摆脱进程组,摆脱原终端完全独立) 52 53 54 sa.sa_handler = SIG_IGN; 55 sigemptyset(&sa.sa_mask); 56 sa.sa_flags = 0; 57 if (sigaction(SIGHUP, &sa, NULL) < 0)//忽略SIGHUP信号 58 exit(1); 59 if ((pid = fork()) < 0) 60 exit(1); 61 else if (pid != 0) /* parent */ 62 exit(0); 63 64 65 if (chdir("/") < 0) //第四步当前的工作目录改为根目录 66 exit(1); 67 68 69 if (getrlimit(RLIMIT_NOFILE, &rl) < 0)//第五步关闭不需要的文件描述符 70 exit(1); 71 if (rl.rlim_max == RLIM_INFINITY) 72 rl.rlim_max = 1024; 73 for (i = 0; i < rl.rlim_max; i++) 74 close(i); 75 76 77 78 fd0 = open("/dev/null", O_RDWR);//第六步打开空文件,使其具有0,1,2描述符 79 fd1 = dup(0); 80 fd2 = dup(0); 81 82 /* 83 openlog(cmd, LOG_CONS, LOG_DAEMON);//第七步打开日志文件 84 if (fd0 != 0 || fd1 != 1 || fd2 != 2) { 85 syslog(LOG_ERR, "unexpected file descriptors %d %d %d", 86 fd0, fd1, fd2); 87 exit(1); 88 }*/ 89 } 90 91 92 93 static int save_xml(int a_fd) 94 { 95 char buf[BUF_SIZE]; 96 ssize_t numRead; 97 int file_d; 98 99 while ((numRead = read(a_fd, buf, BUF_SIZE)) > 0) { 100 101 file_d=open("file_xml",O_RDWR|O_CREAT); 102 if(file_d==-1) 103 exit(1); 104 105 if (write(file_d, buf, numRead) != numRead) { 106 //syslog(LOG_ERR, "write() failed: %s", strerror(errno)); 107 exit(1); 108 } 109 110 if(close(file_d)==-1) 111 exit(1); 112 } 113 114 if (numRead == -1) { 115 //syslog(LOG_ERR, "Error from read(): %s", strerror(errno)); 116 exit(1); 117 } 118 } 119 120 121 122 int main(int argc,char**argv) 123 { 124 125 daemon_init(); 126 127 int listenfd, connfd; 128 pid_t childpid; 129 socklen_t clilen; 130 struct sockaddr_in cliaddr, servaddr; 131 int save_xml(int); 132 133 134 listenfd = socket(AF_INET, SOCK_STREAM, 0);//第一步建立套接字 135 136 bzero(&servaddr, sizeof(servaddr)); 137 servaddr.sin_family = AF_INET; 138 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 139 servaddr.sin_port = htons(8888); 140 141 bind(listenfd, &servaddr, sizeof(servaddr));//第二部绑定一个端口 142 143 listen(listenfd, LISTENQ);//第三步侦听 144 145 //Signal(SIGCHLD, sig_chld); /* must call waitpid() */ 146 147 for ( ; ; ) {//并发 148 clilen = sizeof(cliaddr); 149 if ( (connfd = accept(listenfd, &cliaddr, &clilen)) < 0) {//第四步等待建立连接 150 if (errno == EINTR) 151 continue; /* back to for() */ 152 else 153 exit(1); 154 } 155 156 if ( (childpid = fork()) == 0) { /* child process */ 157 close(listenfd); /* close listening socket */ 158 save_xml(connfd); /* process the request */ 159 exit(0); 160 } 161 close(connfd); /* parent closes connected socket */ 162 } 163 }
原文:http://www.cnblogs.com/kongchung/p/4800941.html