Unix/Linux守護程式伺服器示例
服務端程式碼:
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/wait.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAXFD 100
#define LISTENQ 100
#define BUFSIZE 4096
void sig_child(int signo) {
int ppid;
while ((ppid = waitpid(-1,NULL,WNOHANG)) > 0) {
syslog(LOG_NOTICE,"child process number: %d terminated",ppid);
}
}
void server_echo(int fd) {
char buf[BUFSIZE];
int n;
time_t t = time(NULL);
strftime(buf,BUFSIZE,"%Y %x %X",localtime(&t));
int len = strlen(buf);
buf[len - 1] = '\n';
buf[len] = '\0';
if (write(fd,buf,strlen(buf)) != strlen(buf)) {
syslog(LOG_ERR,"pid: %d write error: %s\n",getpid(),strerror(errno));
exit(1);
}
}
int main(int argc,char **argv) {
if (argc != 2) {
printf("please add <service name or port\n");
exit(1);
}
int pid;
if ((pid = fork()) < 0) {
printf("fork error: %s\n",strerror(errno));
exit(1);
}else if (pid) {
exit(0);
}
if (setsid() < 0) {
printf("setsid error: %s\n",strerror(errno));
exit(1);
}
if (signal(SIGHUP,SIG_IGN) == SIG_ERR) {
syslog(LOG_ERR,"pid: %d fork error: %s\n",getpid(),strerror(errno));
exit(1);
}
umask(0);
if ((pid = fork()) < 0) {
syslog(LOG_ERR,"pid: %d fork error: %s\n",getpid(),strerror(errno));
exit(1);
}else if (pid) {
exit(0);
}
chdir("/");
for (int i = 0; i < MAXFD; ++i) {
close(i);
}
open("/dev/null",O_RDONLY);
open("/dev/null",O_RDWR);
open("/dev/null",O_RDWR);
struct addrinfo hints;
bzero(&hints,sizeof(struct addrinfo));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
struct addrinfo* results;
int err;
if ((err = getaddrinfo(NULL,argv[1],&hints,&results)) != 0) {
syslog(LOG_ERR,"pid: %d getaddrinfo error: %s\n",getpid(),gai_strerror(err));
exit(1);
}
int sockfd;
struct addrinfo* dummy = results;
for (; dummy != NULL; dummy = dummy->ai_next) {
if ((sockfd = socket(dummy->ai_family,dummy->ai_socktype,dummy->ai_protocol)) < 0) {
continue;
}
if (bind(sockfd,dummy->ai_addr,dummy->ai_addrlen) == 0) {
break;
}
close(sockfd);
}
if (dummy == NULL) {
freeaddrinfo(results);
syslog(LOG_NOTICE,"pid: %d all connect failed\n",getpid());
exit(1);
}
freeaddrinfo(results);
if (listen(sockfd,LISTENQ) < 0) {
syslog(LOG_ERR,"pid: %d listen error: %s\n",getpid(),strerror(errno));
exit(1);
}
if (signal(SIGCHLD,sig_child) == SIG_ERR) {
syslog(LOG_ERR,"pid: %d signal error: %s\n",getpid(),strerror(errno));
exit(1);
}
int connfd;
for (; ;) {
errno = 0;
if ((connfd = accept(sockfd,NULL,NULL)) < 0) {
if (errno == EINTR) {
continue;
}
syslog(LOG_ERR,"pid:%d accept error: %s\n",getpid(),strerror(errno));
exit(1);
}
if ((pid = fork()) < 0) {
syslog(LOG_ERR,"pid:%d fork error: %s\n",getpid(),strerror(errno));
exit(1);
}else if (pid == 0) {
close(sockfd);
server_echo(connfd);
close(connfd);
exit(0);
}
close(connfd);
}
return 0;
}
客戶端程式碼:
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#define BUFSIZE 4096
int main(int argc,char **argv) {
if (argc != 3) {
printf("please add <ip address or host name> <service name or port>\n");
exit(1);
}
struct addrinfo hints;
bzero(&hints,sizeof(struct addrinfo));
hints.ai_flags = AI_ALL;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
struct addrinfo* results;
int err;
if ((err = getaddrinfo(argv[1],argv[2],&hints,&results)) != 0) {
printf("getaddrinfor error: %s\n",gai_strerror(err));
exit(1);
}
struct addrinfo* dummy = results;
int sockfd;
for (; dummy != NULL; dummy = dummy->ai_next) {
if ((sockfd = socket(dummy->ai_family,dummy->ai_socktype,dummy->ai_protocol)) < 0) {
continue;
}
if (connect(sockfd,dummy->ai_addr,dummy->ai_addrlen) == 0) {
break;
}
close(sockfd);
}
char recv[BUFSIZE];
int n;
while ((n = read(sockfd,recv,BUFSIZE)) > 0) {
if (write(STDOUT_FILENO,recv,n) != n) {
printf("write error: %s\n",strerror(errno));
exit(1);
}
}
return 0;
}
相關文章
- 理解linux/unix作業系統守護程式(轉)Linux作業系統
- Windows守護程式簡單示例Windows
- Linux 守護程式Linux
- Linux 守護程式和超級守護程式(xinetd)Linux
- 《Unix 網路程式設計》13:守護程式和 inetd 超級伺服器程式設計伺服器
- Linux守護程式及SystemdLinux
- Linux下的守護程式分析Linux
- 深入理解Linux守護程式Linux
- 守護程式
- Linux基礎命令---httpd守護程式Linuxhttpd
- Linux守護程式的啟動方法Linux
- Linux下開發-守護程式(daemon)Linux
- Linux 守護程式的啟動方法Linux
- Node 程式守護
- rstatd守護程式
- gated 守護程式
- RedHat linux 9守護程式一覽(轉)RedhatLinux
- 程式守護 supervisor
- 守護程式那些事
- Linux守護程式的程式設計實現(轉)Linux程式設計
- PHP 實現守護程式PHP
- Golang 程式守護 SupervisorGolang
- PHP 編寫守護程式PHP
- Python編寫守護程式程式Python
- linux中守護程式啟停工具start-stop-daemonLinux
- 物聯網教程Linux系統程式設計——特殊程式之守護程式Linux程式設計
- 守護程序
- hadoop不能互相訪問和linux防火牆守護程式HadoopLinux防火牆
- rsync 守護程式及實時同步
- rsync 守護程式備份報錯
- opentracker改造為daemon守護程式
- 程式守護系統,你懂嗎?
- 用Python實現守護程式Python
- 一個簡單的守護程式
- 用C語言在Linux系統下建立守護程式(Daemon)C語言Linux
- 深入理解Linux作業系統下的守護程式(轉)Linux作業系統
- 深入理解Linux作業系統下的守護程式(1)Linux作業系統
- 深入理解Linux作業系統下的守護程式(2)Linux作業系統