1.多进程并发服务器需要注意的点就是回收子进程的资源
2.使用linux下的nc命令可以测试连接效果
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#define SERVER_PORT (8888)
#define MAX_BUF_SIZE (1024)
void cat_child(int num)
{
pid_t pid = 0;
while(1)
{
pid = waitpid(-1, NULL,WNOHANG);
if(pid <= 0)
{
break;
}
else
{
printf("catch process\n");
continue;
}
}
}
int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
int n;
again:
n = accept(sockfd,addr,addrlen);
if(n < 0)
{
if(errno == EINTR || errno == ECONNABORTED)
{
goto again;
}
else
{
return -1;
}
}
return n;
}
void handle_request(int connfd)
{
pid_t pid = 0;
unsigned char buf[MAX_BUF_SIZE] = {0};
int n = 0;
pid = fork();
if(pid > 0)// 父进程
{
close(connfd);
struct sigaction act;
act.sa_handler = cat_child;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGCHLD,&act,NULL);
}
else if(pid == 0)
{
while(1)
{
n = read(connfd,buf,sizeof(buf));
if(n == 0)
{
printf("client close\n");
break;
}
printf("recv:%s\n",buf);
n = write(connfd, buf,n);
}
}
}
/*处理客户端的连接*/
void handle_connect(int sokcfd)
{
int n = 0;
int iRet = 0;
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);
unsigned char ip[32] = {0};
while(1)
{
n = Accept(sokcfd, (struct sockaddr*)&cliaddr, &len);
if(n < 0)
{
return;
}
//const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);
printf("client addr:%s\n",inet_ntop(AF_INET,&cliaddr,ip,sizeof(ip)));
//处理请求
handle_request(n);
}
}
int main(int argc, char *argv[])
{
struct sockaddr_in seraddr;
int iRet = 0;
//将SIGCHLD加入到阻塞集
sigset_t set;
sigemptyset(&set);
sigaddset(&set,SIGCHLD);
sigprocmask(SIG_BLOCK,&set, NULL);
//创建套接字
int sockfd = 0;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
printf("socket error\n");
return -1;
}
//bind
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(SERVER_PORT);
seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
iRet = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if(iRet < 0)
{
printf("bind error\n");
return -1;
}
//listen
listen(sockfd, 128);
//处理连接
handle_connect(sockfd);
close(sockfd);
return 0;
}