linux 消息队列的单工通信,半双工通信

一 回顾

1 通过 fgets函数实现输入指令
2 再通过 msgnsd 函数读取 值 
3 最后通过 msgrcv函数获取 值  输出 
本质 只是在读 键盘的值  最后结果是 输出显示 

二 消息队列的单工通信

半双工通信

一方为 接收 另一方为发送 通信为单项 
复制两份代码  一个写接收函数 一个写发送函数 

但是这里存在一个问题 你怎么确定 它发送去哪里 谁接收了呢

也就是要确定 一个id 地址 用 ftok函数确定  

在这里插入图片描述

本质的含义
在这里插入图片描述

就是对某个结点 读写  (接收和的发送)

写的部分

//#include <sys/type.h>
#include <stdio.h>

#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>



struct mtype
{
 long mtybe;
 char atext[128];

}sendbuff,readbuff;

int main()
{
      key_t key;
      int res;
      int ipc_id;
      
    /* ftok :让消息队列产生交流的函数 返回值是最后的结果
      也就是 frok 的 结果是让他们建立通信的桥梁(key)*/
      
       key=ftok("duqu.c",1);
    
     ipc_id= msgget(key,IPC_CREAT|0755);
     
      if(ipc_id==-1) return -1;  
     
     printf("succed id is %d\n",ipc_id);    
  
      sendbuff.mtybe=100;

      while(1)
      {
                memset(sendbuff.atext,0,128);	//清除遗留数据 
            
              fgets(sendbuff.atext,128,stdin);//重新输入 
           
             msgsnd(ms,(void *)&sendbuff,strlen(sendbuff.atext),0);//读取输入 
      }


    return 0;
}

                                                          
IPC_CREAT :没有就创建 
frok 函数返回值就是 key 值 并且和 msgget 配合使用 所以msgget 的 一个参数改为 ftok的返回值 

还有一种情况 用了 IPC_CREAT 但是出现这个错误

在这里插入图片描述
解决

直接 touch xx.c 就行了 

获取函数 部分


#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>

struct mtype
{
 long mtybe;
 char atext[128];

}sendbuff,readbuff;

int main()
{
      key_t key;
      int res;
      int rs;
      int ms;
      key=ftok("duqu.c",1);
      ms=msgget(key,IPC_CREAT|0755);

      if(ms==-1)return -2;
      printf("ms: %d\n",ms);

      sendbuff.mtybe=100;

       while(1)
       {
              
         memset(readbuff.atext,0,128);//清除遗留数据 
         
      rs=msgrcv(ms,(void *)&readbuff,128,100,0); 
      printf("read is %s\n",readbuff.atext);
      printf("len is %d\n",rs);

       }
    return 0;
}


}

```csharp
开 两个终端  一个 下载  读 函数  一个 下载 写函数 

在这里插入图片描述

成功 

三 消息队列的半双工通信

在上一节的读写函数 上加 fork 函数  和 父子进程判断 而已 

注意 全双工可以这样
在这里插入图片描述

圈圈表示一个家庭 里面是成员

半双工

两方在某个时刻可接收发送

比如 用父子进程作为通信的对象

父进程 发送 (另外一边的父进程接收)

#include <sys/type.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

strcut mtype
{
 long mtybe;
 char atext[128];

}sendbuff,readbuff;

int main()
{
      int key;
      int rs;
      pid_t pid;
 
      key=ftok("duqu.c",1); 
      
      if(key==-1)
      {
          perror("why;");
          return -2;
      }
      
      int ipc_id=msgget(key,IPC_CREAT|0777);
      
      sendbuff.mtybe=100;
     
      pid=fork();//产生子进程
      
      if(pid>0)
      {
            while(2)
            {       
                   memset(sendbuff.atext,0,128);
                   fgets(sendbuff.atext,128,stdin);//输入 
                   msgsnd(ipc_id,(void *)&sendbuff,strlen(sendbuff.atext),0);//读取输入 
            }
          
      }
        if(pid==0)
      {
            while(2)
            {
                   memset(readbuff.atext,0,128);  
                   rs=msgrcv(ipc_id,(void *)&readbuff,128,200,,0);//获取
                   printf("read is %s\n",readbuff.atext);
                   printf("len is %d\n",rs);
                    
            }
          
      }
    
    return 0;
}

子进程 发送 (另外一边的子进程接收)

#include <sys/type.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

strcut mtype
{
 long mtybe;
 char atext[128];

}sendbuff,readbuff;

int main()
{
      int key;
      int rs;
      pid_t pid;
 
      key=ftok("a.c",1);
      
      if(key==-1)
      {
          perror("why;");
          return -2;
      }
      
     int ipc_id = msgget(key,IPC_CREAT|0777);
      
      sendbuff.mtybe=200;
     
      pid=fork();//产生子进程
      
      if(pid==0)
      {
            while(2)
            {
                    memset(sendbuff.atext,0,128);  
                    fgets(sendbuff.atext,128,stdin);//输入 
                   msgsnd(ipc_id ,(void *)&sendbuff,strlen(sendbuff.atext),0);//读取输入 
            }
          
      }
        if(pid>0)//(另外一边的父进程接收)
      {
            while(2)
            {
                   memset(readbuff.atext,0,128);  
                   rs=msgrcv(ipc_id ,(void *)&readbuff,128,100,,0);//获取
                   printf("read is %s\n",readbuff.atext);
                   printf("len is %d\n",rs);
                    
            }
          
      }
    
    return 0;
}

在这里插入图片描述
如果 在 复制过来的代码 改成了 半双工 通讯 ftok函数的c文件 是一样的 需要编译前 把 c文件 删除 再创建 因为消息队列 写一次 读一次 否则 在代码 运行时 会一直读到空的数据
输入多少 是不确定的 所以用 sizeof 确定 读取对方的数据是确定的 对方发送多少 就读多少

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值