利用有名管道&无名管道 实现 简单的多人聊天

多人登陆 向服务器发送消息,然后服务器能向刚向她发消息的 客户端回发,当前的bug是 服务器连续向同一客户端发送消息时,客户端会一直接收到第二条信息,待修改;


客户端利用子进程的ID建有名管道用于与服务器端通信,服务器端建一公共管道用于与客户端通信

/*server.c 服务器端*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>


#define MAXSIZE 100


struct MSG{
	//pid_t id;
	char id[20];
	char str[MAXSIZE];


};


int main(int argc,char *argv[])
{	
	struct MSG msg;
	pid_t pid;
	int fd[2];
	int pfd;
	char profifo[MAXSIZE],pipebuf[20],comfifo[MAXSIZE];
	if(argc < 2){
		printf("argument error!\n");
		exit(-1);
	}
	if(pipe(fd) < 0){
		printf("pipe error!");
		exit(-2);
	}


	if((pid = fork()) == -1){
		perror("fork()error!");
		exit(-2);
	}
	else if(pid == 0){
		while(1){
			close(fd[1]);//close pipe  write
			//printf("close pipe write over\n");
			read(fd[0] ,pipebuf,sizeof(pipebuf));//read from pipe & get the name of client fifo file
			if( (pfd = open(pipebuf,O_WRONLY)) < 0){
				perror("open profifo error!");
				exit(-3);
			}
		//	printf("after open the pipebuf\n");
		//	printf(">%s>",pipebuf);//output the name of client fifo file
			fgets(profifo,sizeof(profifo),stdin);
			printf("send to client:%s",profifo);
			write(pfd,profifo,strlen(profifo) + 1);//send msg to client
		}
	}else if(pid > 0){
		if( (mkfifo(argv[1],0666) < 0)){
			perror("fail to comman fifo");
			exit(-4);
		}
	//	printf("commfifo maked\n");
		if( (pfd = open(argv[1],O_RDONLY)) < 0){
			perror("fail to open comman fifo");
			exit(-5);
		}
	//	printf("open comfifo sucess\n");
		while(1){
			read(pfd,comfifo,sizeof(comfifo));//read from comfifo
			//divide the id and msg
			char *s = strtok(comfifo," ");
			strcpy(msg.id,s);
			s = strtok(NULL," ");
			strcpy(msg.str,s);
			printf("client id:%s client msg->%s\n",msg.id,msg.str);
			///close pipe read
			close(fd[0]);
			write(fd[1],msg.id,strlen(msg.id) + 1);//write client's id to pipe & send to sonProc
		}
		
	}


	return 0;
}


/*client  客户端*/

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<string.h>
#define MAXSIZE 100

int main(int argc,char *argv[])
{
	pid_t pid;
	int pfd;
	char profifo[100],comfifo[MAXSIZE];
	char proname[20];
	char msg[MAXSIZE];
	if(argc < 2){
		printf("argument error!");
		exit(-1);
	}

	if( (pid = fork()) < 0){
		fprintf(stdout,"fork() error !");
		exit(-2);
	}else if(pid == 0){
		//
		sprintf(proname,"%d",getpid());
		if( (mkfifo(proname,0666) < 0) ){//depend pid mk the profifo
			printf("mkfifo error!");
			exit(-3);
		}
	//	printf("mk profifo sucess!\n");
		if( (pfd = open(proname,O_RDONLY)) < 0){
			perror("fail to open profifo");
			exit(-4);
		}//printf("open profifo sucess\n");

		//memset(profifo,0,sizeof(profifo));
		//get  msg from server
		while(1){
		//	sleep(2);
		//	printf("before read from server\n");
			read(pfd,profifo,sizeof(profifo));
			printf("get from server:%s",profifo);
		}
	}else if(pid > 0){
			if( (pfd = open(argv[1],O_WRONLY)) < 0){
				perror("fail to open comman fifo file");
				exit(-5);
			}
		//	printf("open com fifo sucess\n");
			while(1){
				fgets(msg,sizeof(msg),stdin);//get msg from stdin
				sprintf(comfifo,"%d %s",pid,msg);
				printf("send to server :%s\n",comfifo);
				write(pfd,comfifo,strlen(comfifo) + 1);
				}
	}

	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值