一 回顾
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 确定 读取对方的数据是确定的 对方发送多少 就读多少
。