下面是两个相互通信进程的简单实现,一个代表客户端A,一个代表客户端B
/***************************************
客户端A
发送TYPEB类型的数据到客户端B
读取发送到客户端A的TYPEA类型的数据
***************************************/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <errno.h>
#define N 64
#define TYPEA 100
#define TYPEB 200
typedef struct{
long mtype; //消息类型
char mtext[N]; //正文段
}MSG;
int main()
{
key_t key;
pid_t pid;
int msgid;
MSG buf;
memset(buf.mtext, 0, N); //先将正文段初始化
if ((key = ftok("/", 1)) == -1) {perror("get key"); return -1;} //创建key
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {perror("msgget"); return -1;} //创建消息队列,没有则创建,有了则打开,并将其ID传给msgid
if ((pid = fork()) == -1) {perror("fork"); return -1;}
if (pid == 0) /*子进程从消息队列读取TYPEA类型的消息*/
{
while (1)
{
if (-1 == msgrcv(msgid, &buf, N, TYPEA, 0))
{
perror("msgrcv");
return -1;
}
printf("rcv----%s", buf.mtext);
if (strncmp(buf.mtext, "quit", 4) == 0)
{
kill(getppid(), SIGKILL); //杀死父进程
if (-1 == msgctl(msgid, IPC_RMID, NULL)) //删除消息队列
{
perror("msg rm");
exit(-1);
}
exit(0);
}
}
}
else /*父进程向消息队列发送TYPEB类型的消息*/
{
buf.mtype = TYPEB;
while (1)
{
fgets(buf.mtext, N, stdin);
if (-1 == msgsnd(msgid, &buf, strlen(buf.mtext)+1, 0)) //发送的是正文段的大小,而不是结构体的大小
{
perror("msgsnd");
return -1;
}
if (strncmp(buf.mtext, "quit", 4) == 0)
{
kill(pid, SIGKILL); //杀死子进程
exit(0);
}
}
}
return 0;
}
/***************************************
客户端B
发送TYPEA类型的数据到客户端A
读取发送到客户端B的TYPEB类型的数据
***************************************/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <errno.h>
#define N 64
#define TYPEA 100
#define TYPEB 200
typedef struct{
long mtype; //消息类型
char mtext[N]; //正文段
}MSG;
int main()
{
key_t key;
pid_t pid;
int msgid;
MSG buf;
memset(buf.mtext, 0, N); //先将正文段初始化
if ((key = ftok("/", 1)) == -1) {perror("get key"); return -1;}
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {perror("msgget"); return -1;}
if ((pid = fork()) == -1) {perror("fork"); return -1;}
if (pid == 0) /*child process receive message TYPEA*/
{
while (1)
{
if (-1 == msgrcv(msgid, &buf, N, TYPEB, 0))
{
perror("msgrcv");
exit(-1);
}
printf("rcv----%s", buf.mtext);
if (strncmp(buf.mtext, "quit", 4) == 0)
{
kill(getppid(), SIGKILL);
if (-1 == msgctl(msgid, IPC_RMID, NULL))
{
perror("msg rm");
exit(-1);
}
exit(0);
}
}
}
else /*parent process send message TYPEA*/
{
buf.mtype = TYPEA;
while (1)
{
fgets(buf.mtext, N, stdin);
if (-1 ==msgsnd(msgid, &buf, strlen(buf.mtext)+1, 0))
{
perror("msgsnd");
return -1;
}
if (strncmp(buf.mtext, "quit", 4) == 0)
{
kill(pid, SIGKILL);
exit(0);
}
}
}
return 0;
}