简单的多进程并发服务器

简单的多进程并发服务器

服务器端代码如下:

#include"mylib.h"

int ipv4_tcp_creat_socket(void)
{
	int opt;
	socklen_t len;
	int listenfd;
	struct sockaddr_in server;

	if((listenfd = socket(AF_INET,SOCK_STREAM,0))<0)
	{
		perror("Creat socket failed\n");
		return -1;
	}
	
	//监听套接字,地址可重用
	if((setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)))<0)
	{
		perror("Error,set socket reuse addr failed\n");
		return -2;
	}
	
	bzero(&server,sizeof(server));
	server.sin_family	= AF_INET;
	server.sin_port = htons(SERV_PROT);
	//server.sin_addr.s_addr = inet_addr("127.0.0.1");
	//inet_pton(AF_INET,"127.0.0.1",&server.sin_addr);
	server.sin_addr.s_addr =  htonl(INADDR_ANY);
	
	len = sizeof(struct sockaddr);
	if(bind(listenfd,(struct sockaddr*)(&server),len)<0)
	{
		perror("bind error\n");
		return -3;
	}
	
	listen(listenfd,MAX_LISTEN_QUE);
	
	return listenfd;
}	

int process_data(int sockfd)
{
	int bytes;
	char read_buf[MAX_BUFFER_SIZE];
	memset(read_buf,0x00,MAX_BUFFER_SIZE);
	
	while(1)
	{
		bytes = recv(sockfd,read_buf,100,0);
		if(bytes<0)
		{
			printf("read err\n");
			return -1;
		}
		
		if(bytes == 0)
		{
			printf("client connect closed\n");
			//close(sockfd);
			return 0;
		}
		
		printf("Bytes:%d\n",strlen(read_buf));
		printf("read_buf:%c %c %c\n",read_buf[0],read_buf[1],read_buf[2]);
		
	    if(read_buf[0]=='Q')
		{
			return 0;
		}
		
		if(!strcmp(read_buf,"Tony")) 
		{
			printf("I received Tony\n");
			sprintf(read_buf,"%s","I received Tony\n");
			send(sockfd,read_buf,strlen(read_buf),0);
		}
		else
		{
			send(sockfd,read_buf,bytes,0);
		}
		
		memset(read_buf,0x00,MAX_BUFFER_SIZE);
	}
	
	close(sockfd);
	return 0;

}
//信号处理函数
int process_signal(int signo)
{
	switch(signo)
	{
		case SIGCHLD:
			printf("The client disconnected\n");
			//-1表示所以进程 回收
			while(waitpid(-1,NULL,WNOHANG)>0);
			break;
	}

}

int set_signal_handler(void)
{
	struct sigaction act,oact;
	act.sa_handler = (void *)process_signal;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
    //SA_RESTART 被信号中断的系统调用会自行重启
	act.sa_flags |= SA_RESTART;
	if(sigaction(SIGCHLD,&act,&oact)<0)
	{
		return -1;
	}
	return 0;
}

int main(int argc,char *argv[])
{
	int listenfd,sockfd;
	socklen_t len;
	int bytes = 0;
	struct sockaddr_in server,client;

    set_signal_handler();
	
	len = sizeof(struct sockaddr);
	
	listenfd = ipv4_tcp_creat_socket();

	while(1)
	{
		sockfd = accept(listenfd,(struct sockaddr *)&client,&len);
		if(sockfd<0)
		{
			perror("accept error\n");
			return -1;
		}

		printf("sockfd = %d\n",sockfd);
		printf("IP:%s,Port:%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
		

		if(fork()==0)
		{
			close(listenfd);
			process_data(sockfd);
			exit(0);
		}

		close(sockfd);
		
	}
	return 0;
}

实验结果:

简单的多进程并发服务器_第1张图片

客户端关闭时服务器会杀死其僵尸进程

简单的多进程并发服务器_第2张图片

 

你可能感兴趣的:(Linux)