多进程服务器
注意:包含了“wrap.c” 和“wrap.h”文件在上篇博客中
/*** server.c ***/ #include<stdio.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include<signal.h> #include<sys/wait.h> #include<ctype.h> #include<unistd.h> #include"wrap.h" #define MAXLINE 8192 #define SERV_PORT 8000 int main() { pid_t pid; int lfd,cfd; struct sockaddr_in serv_addr,clie_addr; socklen_t clie_addr_len; char buf[BUFSIZ]; int n,i; lfd = Socket(AF_INET,SOCK_STREAM,0); bzero(&serv_addr,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(SERV_PORT); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //inet_pton(AF_INET,"192.168.0.1",&serv_addr.sin_addr.s_addr); Bind(lfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); Listen(lfd,128); while(1) { clie_addr_len = sizeof(clie_addr); cfd = Accept(lfd,(struct sockaddr *)&clie_addr,&clie_addr_len); pid = fork(); if(pid < 0) { perror("fork error"); exit(1); } else if(pid == 0) { close(lfd); break; } else { close(cfd); } } if(0 == pid) { while(1) { n = Read(cfd,buf,sizeof(buf)); if( 0 == n) { close(cfd); return 0; } else if(-1 == n) { perror("read error") ; exit(1); } else { for(i = 0; i < n; i++) buf[i] = toupper(buf[i]); write(cfd,buf,n); } } } return 0; }
运行结果:
以上程序由于没有回收机制,所以出现僵尸进程
版本2
使用进程回收函数回收僵尸进程
/*** server.c ***/ #include<stdio.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include<signal.h> #include<sys/wait.h> #include<ctype.h> #include<unistd.h> #include"wrap.h" #define MAXLINE 8192 #define SERV_PORT 8000 void wait_child(int signo) { while(waitpid(0,NULL,WNOHANG) > 0) ; return ; } int main() { pid_t pid; int lfd,cfd; struct sockaddr_in serv_addr,clie_addr; socklen_t clie_addr_len; char buf[BUFSIZ],clie_IP[BUFSIZ]; int n,i; lfd = Socket(AF_INET,SOCK_STREAM,0); bzero(&serv_addr,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(SERV_PORT); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //inet_pton(AF_INET,"192.168.0.1",&serv_addr.sin_addr.s_addr); Bind(lfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); Listen(lfd,128); while(1) { clie_addr_len = sizeof(clie_addr); cfd = Accept(lfd,(struct sockaddr *)&clie_addr,&clie_addr_len); printf("client IP:%s,port:%d\n", inet_ntop(AF_INET,&clie_addr.sin_addr,clie_IP,sizeof(clie_IP)),ntohs(clie_addr.sin_port)); pid = fork(); if(pid < 0) { perror("fork error"); exit(1); } else if(pid == 0) { close(lfd); break; } else { close(cfd); signal(SIGCHLD,wait_child); } } if(0 == pid) { while(1) { n = Read(cfd,buf,sizeof(buf)); if( 0 == n) { close(cfd); return 0; } else if(-1 == n) { perror("read error") ; exit(1); } else { for(i = 0; i < n; i++) buf[i] = toupper(buf[i]); write(cfd,buf,n); write(STDOUT_FILENO,buf,n); } } } return 0; }
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2018-08-25 1059 Prime Factors(25 分)