linux--网络编程---多进程(高并发)服务器与客户端

/*************************************************************************
	> File Name: multi_process_server.c
	> Author: xuchen_allen
	> Mail: [email protected] 
	> Created Time: 2019年02月10日 星期日 18时59分17秒
 ************************************************************************/

#include<stdio.h>
#include<string.h>
#include<arpa/inet.h>
#include<ctype.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/wait.h>
#include<signal.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/socket.h>

#define SER_PORT 8080

void do_sigchld(int mun)
{
	while(waitpid(0,NULL,WNOHANG)>0);
}

int main(void)
{
	//创建套接字:
	struct sockaddr_in ser_add,cli_add;
	socklen_t cli_add_len;
	char buf[2048];
	char str[128];
	int i,n;
	pid_t pid;

	//进行信号处理:
	sigset_t myset;		//定义一个信号集;
	sigemptyset(&myset);//初始化该信号集,此时里面没有任何信号;
	sigaddset(&myset,SIGCHLD);//将SIGCHLD加入到信号集中,再对其进行操作;
	sigprocmask(SIG_BLOCK,&myset,NULL);//将信号集的信号都设定为阻塞状态,这样父进程就不会默认处理SIGCHLD信号(忽略),此时将SIGCHLD放入未决信号表,等待处理;
	printf("SIGCHLD is BLOCK.\n");

	//指定期望的网络协议类型:
	int listenfd = socket(AF_INET,SOCK_STREAM,0);
	if(listenfd<0){
		perror("socket fail");
		exit(1);
	}
	printf("socket success.\n");

	//设置端口复用:
	int opt = 1;
	setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
	//设置端口复用,是为了防止主动断开连接端的TIME_WAIT状态导致断开连接后的2MSL时间内不能重联;
	
	//对ser_adr进行初始化:
	bzero(&ser_add,sizeof(ser_add));
	ser_add.sin_family=AF_INET;
	ser_add.sin_addr.s_addr=htonl(INADDR_ANY);//设置为网络传输格式,因为是要传输给客户端
	ser_add.sin_port=htons(SER_PORT);//设置网络传输格式,因为要传输给客户端;
	printf("init ser_add success, IP is:%d\t,port is %d\n",ser_add.sin_addr.s_addr,ser_add.sin_port);

	int ret =bind(listenfd,(struct sockaddr*)&ser_add,sizeof(ser_add));//设置监听;
	if(ret<0){
		perror("listen fail");
		exit(1);
	}
	printf("bind success\n");

	ret = listen(listenfd,20);//设置监听:
	if(ret<0){
		perror("listen fail");
		exit(1);
	}
	printf("listen success\n");


	printf("Waiting connections...\n");


	int k=0;

	while(1){
	
		cli_add_len = sizeof(cli_add);

		int connfd = accept(listenfd,(struct sockaddr*)&cli_add,&cli_add_len);//开始建立连接;
		if(connfd<0){
			perror("connect fail");
			exit(1);
		}
		else{
			k++;
			printf("创建第 %d 个子进程\n",k);
			pid = fork();
			if(pid<0){
				perror("fork fail\n");
				exit(1);
			}
			else if(pid == 0){//进入子进程
     		close(listenfd);
				while(1){
					int len = read(connfd,buf,sizeof(buf));
					if(len<0){
						perror("read fail");
						exit(1);
					}
					else if(len==0){
						printf("客户端断开连接\n");
						break;
					}
					else{
						char str[256];
						printf("客户端的IP:%s\t,端口:%d\n",inet_ntop(AF_INET,&cli_add.sin_addr,str,sizeof(str)),ntohs(cli_add.sin_port));
						int len_w=write(STDOUT_FILENO,buf,len);//把从客户端读到的内容打印到屏幕;
						if(len_w<0){
							perror("write fail");
							exit(1);
						}
					}
				}
				close(connfd);
				return 0;//此时会发出一个SIGCHLD信号
			}
			else{//进入父进程:
				struct sigaction act;
				act.sa_flags = 0;
				act.sa_handler = do_sigchld;
				sigemptyset(&act.sa_mask);
				sigaction(SIGCHLD,&act,NULL);
				//将SIGCHLD解除屏蔽:
				sigprocmask(SIG_UNBLOCK,&myset,NULL);
				close(connfd);
			}
		}
	}
	return 0;
}

/*************************************************************************
	> File Name: client.c
	> Author: xuchen_allen
	> Mail: [email protected] 
	> Created Time: 2019年02月10日 星期日 21时02分17秒
 ************************************************************************/
#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
 
#define _SEVER_IP_ "192.168.1.108"
#define _PORT_ 8080

int main()
{
	int sfd,len;
	struct sockaddr_in serv_addr;
	char buf[1024];
 
	sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0){
		perror("socket fail");
		exit(1);
	}
	else{
		printf("client socket success\n");
	}
 
	bzero(&serv_addr,sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	inet_pton(AF_INET,_SEVER_IP_,&serv_addr.sin_addr.s_addr);
	serv_addr.sin_port = htons(_PORT_);
 
	if(connect(sfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0){
		perror("client conect fail");
		exit(1);
	}
	else{
		printf("client connect success\n");
	}
 
	while(1){
		fgets(buf,sizeof(buf),stdin);
		int r = write(sfd,buf,strlen(buf));
		if(r<0){
			perror("client write fail");
			exit(1);
		}
		printf("write=============== %d\n",r);
		}
	close(sfd);
 
 
	return 0;
}

顺便复习一下信号~~

发布了158 篇原创文章 · 获赞 37 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/XUCHEN1230/article/details/86933038