LINUX下多进程版服务器模型
多进程服务器实现代码
#include "wrap.h"
#include <signal.h>
#include <ctype.h>
#include <sys/wait.h>
//回收子进程函数
void my_wait()
{
pid_t wpid;
while(1)
{
wpid = waitpid(-1, NULL, WNOHANG);
if(wpid > 0)
{
printf("回收子进程%d\n", wpid);
continue;
}
else
{
//printf("没有待回收子进程");
break;
}
}
}
//信号处理函数
void handler(int signo)
{
switch(signo)
{
case SIGCHLD:
{
my_wait();
break;
}
}
}
//主函数
int main()
{
pid_t pid; //进程id
int lfd, cfd; //监听文件描述符、通信文件描述符
struct sockaddr_in client; //客户端信息
socklen_t addrsize; //sockaddr结构体长度
char IP[16]; //客户端IP
struct sigaction act; //信号处理方式
int sigmake = 1; //信号是否已经注册
sigset_t mask; //信号集
//将SIGCHLD信号阻塞
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &mask, NULL);
lfd = tcp4BindListen(9791, NULL, 128);
while(1)
{
addrsize = sizeof(client);
bzero(&client, addrsize);
bzero(IP, sizeof(IP));
cfd = Accept(lfd, (struct sockaddr *)&client, &addrsize);
const char *ptr = inet_ntop(AF_INET, &client.sin_addr, IP, sizeof(IP));
if(ptr == NULL)
{
perror("inet_ntop error");
exit(-1);
}
pid = fork();
if(pid < 0)
{
perror("fork error");
return -1;
}
else if(pid > 0)
{
//关闭通信文件描述符
close(cfd);
if(sigmake)
{
//信号处理方式初始化
act.sa_handler = handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGCHLD, &act, NULL);
//解除SIGCHLD信号的阻塞
sigprocmask(SIG_UNBLOCK, &mask, NULL);
sigmake = 0;
}
}
else if(pid == 0)
{
printf("%s:%d 建立连接\n", IP, ntohs(client.sin_port));
//关闭监听文件描述符
close(lfd);
int n;
char buf[1024];
while(1)
{
bzero(buf, sizeof(buf));
n = Read(cfd, buf, sizeof(buf));
if(n <= 0)
{
break;
}
printf("%s:%d 接收数据 %s", IP, ntohs(client.sin_port), buf);
/*
核心操作
*/
Write(cfd, buf, n);
}
close(cfd);
printf("%s:%d 断开连接\n", IP, ntohs(client.sin_port));
exit(0);
}
}
close(lfd);
return 0;
}