Linux:实现进程间的群聊(类似于聊天室)

思路:

运用共享内存来存储当前聊天的人数,消息队列来存储消息,线程来实现读取。

先通过create.c来创建共享内存,并初始化

在chat.c中实现信息的读取,在主函数中将消息写进消息队列中,创建线程来实现消息的读取。

每运行一次chatc.c文件,共享内存存储数加1,实现人数的相加,并用for语句将语句写入消息队列中(有多少个人就写多少条)

在线程 void *read2(void *arg) 函数中从消息队列中读取信息并打印,并用全局变量temp记录消息类型,当检测到发送方为自身时跳过这次循环,不予打印。

signal(SIGINT,func);     发送信号 ,当按下Ctrl +C 时,将共享内存中存储的人数减一并退出程序。

create.c 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{
    //1.获取key
    key_t key = ftok(".",'c');
    if(key==-1){
        perror("ftok");
        exit(-1);
    }

    //2.通过key创建ID
    int shmid = shmget(key,4,IPC_CREAT|0666);    //4是字节大小
    if(shmid==-1){
        perror("shmget");
        exit(-2);
    }

    //3.映射共享内存
    void *p = shmat(shmid,0,0);
    if(p==(void *)-1){
        perror("shmat");
        exit(-3);
    }

    //4.使用共享内存
    *((int *)p) = 0;



    //5.解除映射
    shmdt(p);

    return 0;
}

chat.c 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <signal.h>


struct MSG{
    long mtype;//消息类型
    char buf[100];//消息数据
};


int temp;
int msqid;

void func(int sig)                 //按CTRL +c 退出并进行人数的减1
{
   
    key_t key = ftok(".",'c');
        if(key==-1)
    {
        perror("ftok");
        exit(-1);
    }

    int shmid = shmget(key,0,0);
    if(shmid==-1){
        perror("shmget");
        exit(-2);
    }

    //3.映射共享内存
    void *p = shmat(shmid,0,0);
    if(p==(void *)-1){
        perror("shmat");
        exit(-3);
    }


   (*((int *)p))--;
   exit(1);
}

void *read2(void *arg)            //从消息队列中获取信息
{

     struct MSG msg1;
     while(1)
     {
        int res = msgrcv(msqid,&msg1,sizeof(msg1.buf),0,0);  
        if(res==-1)
        {
            perror("msgrcv");
            exit(-3);
        }

        if(msg1.mtype==temp)
            continue;
         printf("收到:%s",msg1.buf);

        }
}

int main()
{
  
    signal(SIGINT,func);


    pthread_t id1;
    key_t key = ftok(".",'c');
        if(key==-1)
    {
        perror("ftok");
        exit(-1);
    }
    
    int msqid = msgget(key,IPC_CREAT|0666);
    if(msqid==-1){
        perror("msgget");
        exit(-2);
    }  

//--------------------线程


    int res = pthread_create(&id1,0,read2,0);

    if(res)
    {
        printf("%s\n",strerror(res));
        //exit(-1);
    }
//-------------------------获取共享内存


    int shmid = shmget(key,0,0);
    if(shmid==-1){
        perror("shmget");
        exit(-2);
    }

    //3.映射共享内存
    void *p = shmat(shmid,0,0);
    if(p==(void *)-1){
        perror("shmat");
        exit(-3);
    }


   temp=++(*((int *)p));                 //人数加1
 //--------------------------消息队列
    
    //3.发送消息
    struct MSG msg1;
    msg1.mtype = (*((int *)p));
    int i;

    while(1)
    {
      
        fgets(msg1.buf,100,stdin);
        for(i=0;i<*((int *)p);i++)
        {
            msgsnd(msqid,&msg1,sizeof(msg1.buf),0);
        }
        
    }

     pthread_join(id1,0);    //等待线程结束
     shmdt(p);

	return 0;
}

 

运行顺序

gcc create.c -o b.out 

./b.out                                 //只需运行一次就可,创建共享内存

gcc chat.c -pthread

./a.out

打开新的终端运行./a.out     进行群聊

猜你喜欢

转载自blog.csdn.net/weixin_41215479/article/details/81536252