作者:手机用户2502868585 | 来源:互联网 | 2023-07-08 10:59
编程实现两个程序:一个服务器server,一个客户机client。
要求:
服务器采用精灵进程的方式在后台运行,常驻内存。
服务器创建并监视有名管道FIFO,一旦发现有数据,服务器将其保存到一个指定的地方。
客户机每隔一段时间产生一个子进程。
客户机的这些子进程将当前系统时间和自身的PID写入有名管道FIFO就退出。
要点:有名管道,进程间的通信。
客户端:
#include "common.h"
void cleanup(int sig)
{wait(NULL);while(waitpid(-1, NULL, WNOHANG) > 0);
}int main()
{signal(SIGCHLD, cleanup);while(1){pid_t pid = fork();if(pid > 0){sleep(1);continue;}if(pid == 0){int fd = open("/home/gec/fifo", O_WRONLY);if(fd == -1){perror("服务器未启动或管道文件打开失败");exit(0);}char buf[50];bzero(buf, 50);time_t t = time(&t);snprintf(buf, 50, "PID:%d 时间:%s",getpid(), ctime(&t));write(fd, buf, strlen(buf));printf("%s", buf);break;}}return 0;
}
服务端
#include "common.h"static bool begin = true;
static FILE *fp;void saveData(const char *buf, int size)
{if(begin){fp = fopen("/home/gec/mylog", "a+");begin = false;}fwrite(buf, size, 1, fp);fflush(fp);
}
void mylog(const char *usrmsg, const char *errmsg)
{char buf[100];bzero(buf, 100);snprintf(buf, 100, "%s:%s\n", usrmsg, errmsg);syslog(LOG_DAEMON, buf);
}int daemon_init(void)
{pid_t pid;int fd0, fd1, fd2, max_fd,i; if((pid &#61; fork()) < 0){perror("fork faild!");exit(1);}else if(pid > 0){exit(0);}printf("第1步成功\n");signal(SIGHUP, SIG_IGN);printf("第2步成功\n");if(setsid() < 0){exit(1);}printf("第3步成功\n");if((pid &#61; fork()) < 0){perror("fork faild!");exit(1);}else if(pid > 0)exit(0);printf("第4步成功\n");setpgrp();printf("第5步成功\n");openlog("Server", LOG_CONS | LOG_PID, LOG_DAEMON);max_fd &#61; sysconf(_SC_OPEN_MAX);for (i &#61; max_fd; i>&#61;0; i--){close(i);}umask(0);chdir("/");return 0;
}int main()
{daemon_init();mkfifo("/home/gec/fifo", 0666);int fd &#61; open("/home/gec/fifo", O_RDWR);if(fd &#61;&#61; -1){mylog("打开管道失败", strerror(errno));exit(0);}char buf[50];while(1){bzero(buf, 50);int n &#61; read(fd, buf, 50);if(n > 0){saveData(buf, n);}else{mylog("读取管道数据失败", strerror(errno));exit(0);}}fclose(fp);close(fd);return 0;
}
思路与步骤&#xff1a;
一、客户端步骤&#xff1a;
- 打开有名管道
- 往管道写入数据
- 管道的读写是在子进程进程进行&#xff0c;执行完任务后就退出了。所以父进程要回收子进程&#xff0c;避免僵尸的长期存在。
二、服务端步骤
- 创建有名管道
- 打开有名管道
- 阻塞等待客户端的信息
- 有数据来的话就创建一个文件来保存客户端的数据
- 服务端应该为一个精灵进程&#xff0c;即我当前的控制终端关闭也不影响我持续不断的监控客户端的数据。