一.msgsnd 函数
功能:把一条消息添加到消息队列中
int msgsnd( int msqid, // 由msgget返回的消息队列标志吗
const void *msgp, // 一个指针,只想准备发送的消息
size_t msgsz, // 是msgp指向消息的长度
int msgflg); // 控制这当前消息队列满或到达系统上限时发生的事情
返回值:
成功返回0
失败返回-1
注意:
msgflg=IPC_NOWAIT表示队列满不等待,返回EAGAIN错误。为0表示阻塞等待
消息结构在两方面受到制约。首先,它的具体数据必须小于系统规定的上限值MSGMAX;其次,它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型。
消息结构参考形式:
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
功能:从一个消息队列接收消息
ssize_t msgrcv(int msqid, //消息队列标识符
void *msgp, // 指针指向准备接收的消息
size_t msgsz, // 消息长度
long msgtyp, // 实现接收优先级的简单形式
int msgflg); //控制着队列中没有相应类型的消息可供接收时将要发生的事msgtype = 0; 总是顺序结束的
返回值:
成功:返回实际放到接收缓冲区里去的字符个数
失败: 返回-1
注意:
msgtype=0 返回队列第一条信息,按顺序接收
msgtype>0 返回队列第一条类型等于msgtype的消息
msgtype<0 返回队列第一条类型小于等于msgtype绝对值的消息,并且是满足条件的消息类型最小的消息
功能:把一条消息添加到消息队列中
int msgsnd( int msqid, // 由msgget返回的消息队列标志吗
const void *msgp, // 一个指针,只想准备发送的消息
size_t msgsz, // 是msgp指向消息的长度
int msgflg); // 控制这当前消息队列满或到达系统上限时发生的事情
返回值:
成功返回0
失败返回-1
注意:
msgflg=IPC_NOWAIT表示队列满不等待,返回EAGAIN错误。为0表示阻塞等待
消息结构在两方面受到制约。首先,它的具体数据必须小于系统规定的上限值MSGMAX;其次,它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型。
消息结构参考形式:
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
功能:从一个消息队列接收消息
ssize_t msgrcv(int msqid, //消息队列标识符
void *msgp, // 指针指向准备接收的消息
size_t msgsz, // 消息长度
long msgtyp, // 实现接收优先级的简单形式
int msgflg); //控制着队列中没有相应类型的消息可供接收时将要发生的事msgtype = 0; 总是顺序结束的
返回值:
成功:返回实际放到接收缓冲区里去的字符个数
失败: 返回-1
注意:
msgtype=0 返回队列第一条信息,按顺序接收
msgtype>0 返回队列第一条类型等于msgtype的消息
msgtype<0 返回队列第一条类型小于等于msgtype绝对值的消息,并且是满足条件的消息类型最小的消息
msgflg=IPC_NOWAIT,队列没有可读消息不等待(不阻塞),返回ENOMSG错误。
msgflg=MSG_NOERROR,消息大小超过msgsz时被截断msgtype>0且msgflg=MSG_EXCEPT,接收类型不等于msgtype的第一条消息。
发送函数msg_send.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
struct msgbuf {
long mtype; // message type, must be > 0
char mtext[1]; // message data
};
int main(int argc,char* argv[])
{
if(argc != 3)
{
fprintf(stderr,"Usage::%s <bytes> <types> \n",argv[0]);
exit(EXIT_FAILURE);
}
int len= atoi(argv[1]); //消息的长度
int type = atoi(argv[2]); // 消息的类型
int msgid;
msgid = msgget(1234,0); // 打开一个1234的消息队列
if(msgid == -1)
ERR_EXIT("msgget err");
struct msgbuf *ptr;
ptr = (struct msgbuf*)malloc(sizeof(long) + len); // 分配空间
ptr->mtype = type;
if( msgsnd(msgid,ptr,len,0) < 0) // 向消息队列中发送消息
ERR_EXIT("msgsnd");
return 0;
}
接收函数msg_rcv.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
#define MSGMAX 8192
struct msgbuf {
long mtype; // message type, must be > 0
char mtext[1]; // message data
};
int main(int argc,char* argv[])
{
int flag =0; // 默认以阻塞
int type =0;
int opt;
while(1)
{
opt = getopt(argc,argv,"nt:"); // nt后面可以各跟一个参数
if(opt == '?')
ERR_EXIT("getopt err");
if(opt == -1)
break;
switch(opt)
{
case 'n':
//printf("AAAA\n");
flag |= IPC_NOWAIT; // 不阻塞的方式接收
break;
case 't':
//printf("BBBB\n");
//int n = atoi(optarg);
//printf("n=%d\n",n);
type = atoi(optarg); // 类型保存,接收对应类型的消息
break;
default:
break;
}
}
int msgid;
msgid = msgget(1234,0);
if(msgid == -1)
ERR_EXIT("msgget err");
struct msgbuf *ptr;
ptr = (struct msgbuf*)malloc(sizeof(long) + MSGMAX);
ptr->mtype = type;
int n=0; // 接收到的字节
if( (n = msgrcv(msgid,ptr,MSGMAX,type,flag)) < 0)
ERR_EXIT("msgsnd");
printf("read %d bytes type=%ld \n",n,ptr->mtype);
return 0;
}
发送:
开始发送1 100 这个消息长度为1,消息类型为100的消息队列的时候,失败,是因为没有创建消息队列, 利用msg_get创建一个消息队列,
接收:
接收可以按照顺序接收,也可以指定消息类型接收,-n选项表示用不阻塞的方式接收消息, -t选项 可以指定按类型接收消息.