撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)

Posted llguanli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)相关的知识,希望对你有一定的参考价值。

一:任务描写叙述

             AB两个进程通过管道通信,像曾经的互相聊天一样,然后A进程每次接收到的数据通过A1进程显示(一个新进程,用于显示A接收到的信息),AA1间的数据传递採用共享内存,相应的有一个B1进程。用于显示B进程接收到的信息。

针对AB进程,退出时採用ctrl+c退出,当收到相应信号后。自身进程可以通过信号处理函数进行资源清理,清理后exit退出进程。(A1B1,手动关闭就可以)。界面图例如以下。


技术分享

:代码展示


A进程

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

int shm_id;

struct t
{
        char buf[128];
};

struct t *p;
void hanle(int sig)
{
        shmdt(p);
        shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
        printf("delete OK........\n");
        exit(0);

}

int main()
{//A进程

        signal(SIGINT,hanle);//捕捉 ctrl+c信号

        shm_id=shmget((key_t)1234,4096,0600|IPC_CREAT);
//创建了一个共享内存

//      struct t *p;
        p=(struct t*)shmat(shm_id,NULL,0);//拿到内存的指针结构体

        int f1;
        f1=open("1.fifo",O_WRONLY);//对1 打开写端

        int f2;
        f2=open("2.fifo",O_RDONLY);//对2 打开读端

        fd_set readset;
        //定义了可读集合
        int maxfd;
        maxfd=STDIN_FILENO > f2 ?

STDIN_FILENO+1:f2+1; struct timeval check; check.tv_sec=1;//设置查看时间是一秒 char buf[128]; while(1) { FD_ZERO(&readset);//初始化 FD_SET(STDIN_FILENO,&readset);//加入监控对象 FD_SET(f2,&readset); select(maxfd,&readset,NULL,NULL,&check);//返回可读的监控对象 if(FD_ISSET(STDIN_FILENO,&readset)) {//假设监控到了1管道中有标准输入 那么获取到数据 写到管道中 memset(buf,0,sizeof(buf)); fgets(buf,sizeof(buf),stdin); buf[strlen(buf)-1]='\0'; write(f1,buf,sizeof(buf));//写到管道1中 } if(FD_ISSET(f2,&readset)) {//监控到了管道2中能够读 memset(buf,0,sizeof(buf)); read(f2,buf,sizeof(buf));//从管道2中读到buf了 strcpy(p->buf,buf);//将管道2中读到的buf 弄到共享内存 printf("from 2: %s\n",buf); } if(strcmp(buf,"bye")==0) { break; } } exit(0); }


B进程

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int shm_id;
struct t
{
        char buf[128];
};
struct t *p;
void hanle(int sig)
{
        shmdt(p);
        shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
        printf("delete OK........\n");
        exit(0);

}
int main()
{//B进程

        signal(SIGINT,hanle);
         shm_id=shmget((key_t)1235,4096,0600|IPC_CREAT);

//      struct t *p;
        p=(struct t*)shmat(shm_id,NULL,0);

        int f1;
        f1=open("1.fifo",O_RDONLY);//对1 打开读端

        int f2;
     f2=open("2.fifo",O_WRONLY);//对2 打开写端

        fd_set readset;
        //定义了可读集合
        int maxfd;
        maxfd=STDIN_FILENO > f1 ? STDIN_FILENO+1:f1+1;

        struct timeval check;
        check.tv_sec=1;//设置查看时间是一秒
        char buf[128];
        while(1)
        {
         FD_ZERO(&readset);//初始化
         FD_SET(STDIN_FILENO,&readset);//加入监控对象
         FD_SET(f1,&readset);
         select(maxfd,&readset,NULL,NULL,&check);//返回可读的监控对象

         if(FD_ISSET(STDIN_FILENO,&readset))
          {//假设监控到了1管道中有标准输入 那么获取到数据 写到管道中
           memset(buf,0,sizeof(buf));
           fgets(buf,sizeof(buf),stdin);
           buf[strlen(buf)-1]='\0';
           write(f2,buf,sizeof(buf));//写到管道2中
          }
         if(FD_ISSET(f1,&readset))
          {//监控到了管道2中能够读
           memset(buf,0,sizeof(buf));
           read(f1,buf,sizeof(buf));//从管道1中读
           strcpy(p->buf,buf);//将读出的字符 放到共享内存中
           printf("from 1:  %s\n",buf);
          }
         if(strcmp(buf,"bye")==0)
          {
           break;
          }

        }
        exit(0);
}

A1进程


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

int shm_id;
struct t
{
        char buf[128];
};
struct t *p;
void hanle(int sig)
{
        shmdt(p);
        shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
        printf("delete OK........\n");
        exit(0);
}

int main()
{
         shm_id=shmget((key_t)1234,4096,0600|IPC_CREAT);
        //获得了共享内存
//      struct t *p;
        p=(struct t*)shmat(shm_id,NULL,0);//这个也拿到了
        char s[128]={0};
        while(1)
        {
        if(strcmp(s,p->buf)!=0)
        {//字符串不同样  那么就打印出来
        strcpy(s,p->buf);
        printf("from B   :%s\n",p->buf);
        }
        }

        exit(0);
}



B1进程

<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>

int shm_id;
struct t
{
        char buf[128];
};
struct t *p;
void hanle(int sig)
{
        shmdt(p);
        shmctl(shm_id,IPC_RMID,NULL);//删除共享内存
        printf("delete OK........\n");
        exit(0);

}
int main()
{
         shm_id=shmget((key_t)1235,4096,0600|IPC_CREAT);
        //获得了共享内存
//      struct t *p;
        p=(struct t*)shmat(shm_id,NULL,0);//这个也拿到了
        char s[128]={0};
        while(1)
        {
        if(strcmp(s,p->buf)!=0)
        {//字符串不同样  那么就打印出来
        strcpy(s,p->buf);
        printf("from A   :%s\n",p->buf);
        }
        }
        exit(0);
}</span><span style="font-size:18px;">
</span>


三:结果显示


技术分享

















以上是关于撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)的主要内容,如果未能解决你的问题,请参考以下文章

高仿微信聊天界面长按弹框样式

16行代码实现微信聊天机器人,自动智能回复,打团了让它来陪老婆聊天

16行代码实现微信聊天机器人,自动智能回复,打团了让它来陪女朋友聊天!

基于Qt的类QQ气泡聊天的界面开发

Android中类似QQ和微信中聊天消息中包含有电话号码,点击可以选择拨打的功能怎么实现?

高级Java开发类QQ聊天工具的设计与实现(代码已上传)