9 多进程并发服务器模型

1. 多进程并发服务器的实现,学习点:

fork子进程处理新客户端连接请求;

通过信号回收断开连接的子进程资源,不会让client主动断开时子进程处于僵死状态;

封装功能函数,实现模块化。

#include "socket_includes.h"
#include <signal.h>


int mz_ipv4_tcp_create_socket(void)
{
	int listenfd, sockfd, opt = 1;
	struct sockaddr_in server, client;
	socklen_t len;
	int timep;
	int ret;

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if(listenfd < 0){
		perror("Create socket fail.");
		return -1;
	} 

	if((ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0){
		perror("Error, set socket reuse addr failed");  
		return -1;
	}

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port   = htons(SERV_PORT);
	server.sin_addr.s_addr  = htonl(INADDR_ANY);
	
	len = sizeof(struct sockaddr);
	if(bind(listenfd, (struct sockaddr *)&server, len)<0){
			  perror("bind error.");
		return -1;
	}
	
	  
	listen(listenfd, MAX_LISTEN_QUE);

	return listenfd;
}

int mz_process_data(int sockfd)
{
	int bytes;
	char buf[MAX_BUFFER_SIZE], read_buf[MAX_BUFFER_SIZE];

	memset(read_buf, 0x00, MAX_BUFFER_SIZE);
	memset(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 connection closed.\n");
			return 0;
		}
		printf("Bytes:%d\n", strlen(read_buf));
		printf("read_buf: %x %x %x \n", read_buf[0], read_buf[1], read_buf[2]);

		send(sockfd, read_buf, bytes, 0);

		if(!strcmp(read_buf, "q")){
			return 0;
		}
		if(!strcmp(read_buf, "c")){
			printf("i love you.\n");
			sprintf(read_buf, "%s","i love you.\n" );
			send(sockfd, read_buf, bytes, 0);
		}
	}
	close(sockfd);
	return 0;
}

int mz_process_signal(int signo)
{
	switch(signo){
		case SIGCHLD:
			printf("dddddddddd\n");
			while(waitpid(-1, NULL, WNOHANG)>0);	
		break;
	}
}

int mz_set_signal_handler(void)
{
	struct sigaction act, oact;
	act.sa_handler = (void *)mz_process_signal;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_flags |= SA_RESTART;
	if(sigaction(SIGCHLD, &act, &oact) < 0){
		return -1;
		}
		return 0;
}

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

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

		printf("sockfd=%d\n", sockfd);
		printf("IP: 0x%x, Port:%d\n", ntohl(client.sin_addr.s_addr), ntohs(client.sin_port));
		if(fork() == 0){
			close(listenfd);
			mz_process_data(sockfd);
			exit(0);
		}
		close(sockfd);
	  

	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值