嵌入式——管道实现聊天室(2)

一、介绍

在我以前发的聊天室的基础上增加私聊功能。
想要对某个用户私聊需要,私聊用户名+@+内容

二、代码

2.1 头文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <signal.h>
#include<unistd.h>
#include<sys/stat.h>
#include <fcntl.h>
#include<linux/stat.h>
#include<sys/types.h>
#include<string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>


#define pubpipe "public"
#define SIZE 1024
#define KEY 99


int w_num;
int *shm=NULL;
int shmid;
int run=1;
int fd,fd1;
pid_t pid,pid2;
char ts1=':';char ts2='@';
char buf1[SIZE],buf2[SIZE],buf_name[SIZE],bufj1[SIZE],bufj2[SIZE];
char buf_data[SIZE][SIZE];

struct shareMemory{
    int num;
	char bufs[SIZE];
	char buf_pri_name[100][100];
};

2.2 服务器

#include"CharRoom3.h"

void main()
{ 
	struct shareMemory *shared; 
	if((shmid=shmget(KEY,SIZE,0666|IPC_CREAT))==-1){
        perror("Fail to shmget");
	exit(EXIT_SUCCESS);}

	//创建公用管道
	if((mkfifo(pubpipe,0777)<0)&&(errno!=EEXIST)){
        printf("cannot create fifo...\n");exit(1);}
	//共享内存,初始化
	shm = shmat(shmid,0,0);
	shared = (struct shareMemory *)shm; 
	if(shared->num!=0)
		shared->num=0;
	
	pid=fork();
	if(pid>0){
		shm = shmat(shmid,0,0);               //设置共享内存
		shared = (struct shareMemory *)shm;      
		while(1){
		shared->num=shared->num;
		if((fd=open(pubpipe,O_RDONLY))==-1){
			printf(" open pubpipe error\n");exit(1);}
		if(read(fd,buf1,SIZE)<0){
			printf("read error!\n");exit(1);}
		if(strncmp(buf1,"pipename",8)==0){
			memcpy(shared->buf_pri_name[shared->num],buf1+8,20);
			printf("new pipe name:%s\n",shared->buf_pri_name[shared->num]);
			shared->num+=1;printf("当前在线人数:%d\n",shared->num);
			memset(buf1, 0, sizeof(buf1));continue;}
		strcpy(shared->bufs,buf1);}
		if(shmdt(shm)==-1)   //把共享内存从当前进程分离
        {
            perror("Fail to shmdt");
            exit(1);
        }
	}
	else{
		shm = shmat(shmid,0,0);                //设置共享内存
		shared = (struct shareMemory *)shm;        
		while(1){
		if(strncmp(buf2,shared->bufs,strlen(shared->bufs))!=0){
		for(int ns=0;ns<shared->num;ns++){
			if((fd1=open(shared->buf_pri_name[ns],O_WRONLY))==-1){
				printf("删除第%d个管道\n",ns);
				printf("%s pipe delete!\n",shared->buf_pri_name[ns]);
				for(int k=ns;k<shared->num;k++)
					strcpy(shared->buf_pri_name[k],shared->buf_pri_name[k+1]);
				shared->num-=1;printf("当前在线人数:%d\n",shared->num);continue;}

			if(write(fd1,shared->bufs,SIZE)<0){
			printf("write error!\n");exit(1);}
			
		}
		strcpy(buf2,shared->bufs);
		}
		
		}
		if(shmdt(shm)==-1)   //把共享内存从当前进程分离
        {
            perror("Fail to shmdt");
            exit(1);
        }
			
	}
}

2.3 客户端

#include"CharRoom3.h"

void main(int argc,char* argv[])
{
	//判断参数个数
	if(argc!=2){
	printf("parameter error!\n");exit(1);}
	
	// 创建私有管道,如果有则直接使用
    if((mkfifo(argv[1],0777)<0)&&(errno!=EEXIST))
    {
        printf("cannot create %s fifo error!\n",argv[1]);
        exit(1);
    }
	
	//发送私有管道名给服务器
	sprintf(buf1,"pipename%s",argv[1]);
    if((fd=open(pubpipe,O_WRONLY))==-1){
       printf(" open pubpipe error\n");exit(1);}
   if(write(fd,buf1,SIZE)<0){
	   printf("write error!\n");exit(1);}
	close(fd);

	//注册
	printf("请输入你的昵称:");scanf("%s",buf_name);
	printf("%d\n",getpid());
	system("date +%m-%d-%I:%M");
	printf("欢迎%s进入聊天室\n",buf_name);
	
	//父子进程实现通讯
	pid=fork();
	if(pid>0){while(1){
		  if((fd=open(pubpipe,O_WRONLY))==-1){
       printf(" open pubpipe error\n");exit(1);}
		scanf("%s",buf1);
		sprintf(buf2,"%s: ",buf_name);
		strcat(buf2,buf1);
	if(write(fd,buf2,SIZE)<0)
		{	printf("write error!\n");exit(1);}
	if(strcmp(buf1,"quit")==0){
		unlink(argv[1]); exit(1);}
	}}
	
	else{while(1){
		sprintf(buf2,"%s@",buf_name);
		memset(buf1, 0, sizeof(buf1));
		if((fd1=open(argv[1],O_RDWR))==-1){
        printf(" open pripipe error\n");exit(1);}
		if(read(fd1,buf1,SIZE)<0){
		printf("write error!\n");exit(1);}
		if(strlen(buf1)!=0){
			if(strncmp(buf1,buf_name,strlen(buf_name))!=0){
				if(strstr(buf1,"@")!=NULL){
					if(strstr(buf1,buf2)!=NULL){
						for(int i=0;i<strlen(buf1);i++){
							if(buf1[i]!=ts1)
								bufj1[i]=buf1[i];
							else break;
						}
						for(int i=0;i<strlen(buf1);i++){
							if(buf1[i]!=ts2)
								continue;
							else {
								for(int j=i+1;j<strlen(buf1);j++)
									bufj2[j-i-1]=buf1[j];
								break;
							}
						}
					sprintf(buf1,"%s private chat you:%s",bufj1,bufj2);
					printf("%s\n",buf1);}
				}
			else 
			 printf("%s\n",buf1);}}
	}}
}

三、演示视频

链接:https://pan.baidu.com/s/15pZ3TPlj1ioBKYuYfcTmdA
提取码:o29f

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值