其他分享
首页 > 其他分享> > 实现多客户端对服务器通信代码

实现多客户端对服务器通信代码

作者:互联网

通过多线程和多进程
多进程版,考虑到了进程回收

#include<stdio.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<ctype.h>
#include<signal.h>
#include<sys/wait.h>
#include"wrap.h"
void waitchild(int signo)
{
	pid_t wpid;

	//回收子进程
	while(1)
	{
		wpid = waitpid(-1, NULL, WNOHANG);
		if(wpid>0)
		{
			printf("child is quit, wpid==[%d]\n", wpid);
		}
		else if(wpid==0)
		{
			printf("child is living, wpid==[%d]\n", wpid);
			break;
		}
		else if(wpid==-1)
		{
			printf("no child is living, wpid==[%d]\n", wpid);
			break;
		}
	}
}


int main()
{
	//创建socket
	//socket(协议版本,协议类型,对应类型的默认协议);
	int lfd = Socket(AF_INET, SOCK_STREAM, 0);

	//准备第二个参数
	struct sockaddr_in serv;
	bzero(&serv,sizeof(serv));
	//TCP版本
	serv.sin_family = AF_INET;
	//端口
	serv.sin_port = htons(8888);
	//IP
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
	//将文件描述符与IP,PORT(serv)绑定
	int ret = Bind(lfd,(struct sockaddr *)&serv,sizeof(serv));

	//监听
	//int listen(int sockfd, int backlog);
	Listen(lfd,128);

	//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
	//printf("accept前\n");

	struct sockaddr_in client;
	int flag = 0;
	//将SIGCHLD信号阻塞
	sigset_t mask;
	sigemptyset(&mask);
	sigaddset(&mask, SIGCHLD);
	sigprocmask(SIG_BLOCK, &mask, NULL);
	while(1)
	{
		socklen_t len = sizeof(client);
		int cfd = Accept(lfd,(struct sockaddr *)&client,&len);
	//	printf("cfd==[%d]\n",cfd);
			printf("lfd==[%d],cfd==[%d]\n",lfd,cfd);


		pid_t pid = fork();
		if(pid<0)
		{
			perror("fork error");
			exit(-1);
		}
		if(pid>0)
		{
			close(cfd);
			if(flag==0)				
			{
				//注册信号处理函数
				struct sigaction act;
				act.sa_handler = waitchild;
				sigemptyset(&act.sa_mask);
				act.sa_flags = 0;
				sigaction(SIGCHLD, &act, NULL);

				//解除对SIGCHLD信号的阻塞
				sigprocmask(SIG_UNBLOCK, &mask, NULL);
				flag++;
			}
		}
		if(pid==0)
		{
			//关闭监听文件描述符
			close(lfd);

			//获取客户端IP和PORT
			char sIP[16];
			memset(sIP,0,sizeof(sIP));
			printf("client的IP:[%s],PORT:[%d]\n",inet_ntop(AF_INET, &client.sin_addr.s_addr, sIP, sizeof(sIP) ),ntohs(client.sin_port));
			//printf("cfd==[%d]\n",cfd);

			int i=0;
			int n=0;
			char buf[1024];
			while(1)
			{
				//读数据
				memset(buf,0,sizeof(buf));
				n = Read(cfd,buf,sizeof(buf));
				if(n<=0)
				{
					printf("read error or client close,n==[%d]",n);
					break;
				}

				printf("[%d]------>n==[%d],buf==[%s]\n",ntohs(client.sin_port),n,buf);

				for(i=0;i<n;i++)
				{
					buf[i] = toupper(buf[i]);
				}

				//发数据
				Write(cfd,buf,n);
			}

			close(cfd);
			exit(0);

		}
	}


	close(lfd);
	return 0;
}

标签:wpid,int,代码,printf,服务器,include,buf,cfd,客户端
来源: https://blog.csdn.net/weixin_50134791/article/details/112390307