dm03_msgsend.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <stdlib.h>
//IPC对象;消息队列是linux内核给你持久化(我们可以从linux内核中获取消息队列的信息,修改消息队列)
//通过msqid删除消息队列 ipcrm -q msqid
/*
//可发送的最长消息字节数
hzmct@U-64:~$ cat /proc/sys/kernel/msgmax
8192
//一个特定队列的最大字节数(这个队列中所有的消息长度之和)
hzmct@U-64:~$ cat /proc/sys/kernel/msgmnb
16384
//系统中的最大消息数
hzmct@U-64:~$ cat /proc/sys/kernel/msgmni
32000
*/
void showq(void * buf)
{
if(buf == NULL)
{
printf("buf == NULL ");
return;
}
struct msqid_ds *msqid_ds = (struct msqid_ds *)buf;
printf("************************show ipc msgq************************\n");
printf("该消息队列对应的键:%x\n", msqid_ds->msg_perm.__key);
printf("该消息队列访问权限:%o\n", msqid_ds->msg_perm.mode);
printf("该消息队列的序号:%d\n", msqid_ds->msg_perm.__seq);
printf("该消息队列 UID of owner:%d\n", msqid_ds->msg_perm.uid);
printf("该消息队列 GID of owner:%d\n", msqid_ds->msg_perm.gid);
printf("该消息队列 UID of creator:%d\n", msqid_ds->msg_perm.cuid);
printf("该消息队列 GID of creator:%d\n", msqid_ds->msg_perm.cgid);
printf("消息队列中的消息个数:%d\n", (int)msqid_ds->msg_qnum);
printf("当前消息队列中有多少字节:%ld\n", (long int)msqid_ds->__msg_cbytes);
printf("该消息最后发送的时间:%ld, 进程id:%d\n", (long int)msqid_ds->msg_stime, msqid_ds->msg_lspid);
printf("该消息最后接收的时间:%ld, 进程id:%d\n", (long int)msqid_ds->msg_rtime, msqid_ds->msg_lrpid);
printf("接收该消息的修改时间:%ld\n", (long int)msqid_ds->msg_ctime);
printf("消息队列所有消息之和最大字节数(取决于系统):%d\n", (int)msqid_ds->msg_qbytes);
}
//按照系统规定定义结构体,第一个成员必须是long
#define BUFSIZE 1024*10 //10k
struct msgbuf {
long mtype; // message type, must be > 0
char mtext[BUFSIZE]; // message data
};
int main(int argc, char ** argv)
{
int msgid;
int ret;
if (argc != 3)
{
fprintf(stderr, "Usage:%s <消息类型 type> <消息字节长度 bytes>\n", argv[0]);
exit(EXIT_FAILURE);
}
//32与64位系统的 类型长度不一样
printf("------sizeof(long):%d\n", (int)sizeof(long));
printf("------sizeof(int):%d\n", (int)sizeof(int));
msgid = msgget(0x1234, 0666|IPC_CREAT);
if (msgid == -1)
{
if (errno == ENOENT)
{
printf("自己检查错误, 消息队列不存在\n");
}
if (errno == EACCES)
{
printf("自己检查错误, 用户进程没有权限访问\n");
}
perror("msgget");
return -1;
}
printf("msgid:%d\n", msgid);
printf("创建消息队列成功\n");
int type = atoi(argv[1]);
int len = atoi(argv[2]);
struct msgbuf msgbuf;
memset(&msgbuf, 0, sizeof(struct msgbuf));
msgbuf.mtype = type;
strcpy(msgbuf.mtext,"1234567890abcdefg123456789abcdefg");
//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//若发送数据的长度小于msgbuf.mtext,则进行截断处理,msgsz不包含消息类型long int的长度
ret = msgsnd(msgid, &msgbuf, len, IPC_NOWAIT);//消息队列满时,非阻塞等待,
if (ret == -1)
{
perror("msgsnd");
}
struct msqid_ds buf;
memset(&buf, 0, sizeof(struct msqid_ds));
//获取队列状态
ret = msgctl(msgid, IPC_STAT, &buf);
if (ret == -1)
{
perror("获取消息队列状态");
}
showq(&buf);
system("ipcs -q");
//删除消息队列
/*ret = msgctl(msgid, IPC_RMID, &buf);
if (ret == -1)
{
perror("删除消息队列");
}
*/
return 0;
}
dm04_msgrecv.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/ipc.h>
//IPC对象;消息队列是linux内核给你持久化(我们可以从linux内核中获取消息队列的信息,修改消息队列)
//通过msqid删除消息队列 ipcrm -q msqid
/*
//可发送的最长消息字节数
hzmct@U-64:~$ cat /proc/sys/kernel/msgmax
8192
//一个特定队列的最大字节数(这个队列中所有的消息长度之和)
hzmct@U-64:~$ cat /proc/sys/kernel/msgmnb
16384
//系统中的最大消息数
hzmct@U-64:~$ cat /proc/sys/kernel/msgmni
32000
*/
void showq(void * buf)
{
if(buf == NULL)
{
printf("buf == NULL ");
return;
}
struct msqid_ds *msqid_ds = (struct msqid_ds *)buf;
printf("************************show ipc msgq************************\n");
printf("该消息队列对应的键:%x\n", msqid_ds->msg_perm.__key);
printf("该消息队列访问权限:%o\n", msqid_ds->msg_perm.mode);
printf("该消息队列的序号:%d\n", msqid_ds->msg_perm.__seq);
printf("该消息队列 UID of owner:%d\n", msqid_ds->msg_perm.uid);
printf("该消息队列 GID of owner:%d\n", msqid_ds->msg_perm.gid);
printf("该消息队列 UID of creator:%d\n", msqid_ds->msg_perm.cuid);
printf("该消息队列 GID of creator:%d\n", msqid_ds->msg_perm.cgid);
printf("消息队列中的消息个数:%d\n", (int)msqid_ds->msg_qnum);
printf("当前消息队列中有多少字节:%ld\n", (long int)msqid_ds->__msg_cbytes);
printf("该消息最后发送的时间:%ld, 进程id:%d\n", (long int)msqid_ds->msg_stime, msqid_ds->msg_lspid);
printf("该消息最后接收的时间:%ld, 进程id:%d\n", (long int)msqid_ds->msg_rtime, msqid_ds->msg_lrpid);
printf("接收该消息的修改时间:%ld\n", (long int)msqid_ds->msg_ctime);
printf("消息队列所有消息之和最大字节数(取决于系统):%d\n", (int)msqid_ds->msg_qbytes);
}
//按照系统规定定义结构体
#define BUFSIZE 1024*10 //10k
struct msgbuf {
long mtype; // message type, must be > 0 类型必须是长整型
char mtext[BUFSIZE]; // message data
};
int main(int argc, char ** argv)
{
int msgid;
int ret;
int type = 0;//消息类型
int flag = 0;
if (argc == 1)
{
fprintf(stderr, "Usage:%s <消息类型 type 0 1 2 3> <n 阻塞>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (argc == 2)
{
type = atoi(argv[1]);//消息类型
}
//若输入3个参数,表示使用非阻塞
if (argc == 3)
{
type = atoi(argv[1]); //消息类型
flag = flag | IPC_NOWAIT; //设置非阻塞
}
//32与64位系统的 类型长度不一样
printf("------sizeof(long):%d\n", (int)sizeof(long));
printf("------sizeof(int):%d\n", (int)sizeof(int));
//接收程序要指定同一个键值
msgid = msgget(0x1234, 0666|IPC_CREAT);
if (msgid == -1)
{
if (errno == ENOENT)
{
printf("自己检查错误, 消息队列不存在\n");
}
if (errno == EACCES)
{
printf("自己检查错误, 用户进程没有权限访问\n");
}
perror("msgget");
return -1;
}
printf("msgid:%d\n", msgid);
printf("创建消息队列成功\n");
struct msgbuf msgbuf;
memset(&msgbuf, 0, sizeof(struct msgbuf));
ret = msgrcv(msgid, &msgbuf, BUFSIZE, type, flag);
if (ret == -1)
{
perror("msgsnd");
}
msgbuf.mtext[ret] = '\0';
printf("mtext:%s\n",msgbuf.mtext);
struct msqid_ds buf;
memset(&buf, 0, sizeof(struct msqid_ds));
//获取队列状态
ret = msgctl(msgid, IPC_STAT, &buf);
if (ret == -1)
{
perror("获取消息队列状态");
}
//showq(&buf);
system("ipcs -q");
//删除消息队列
/*ret = msgctl(msgid, IPC_RMID, &buf);
if (ret == -1)
{
perror("删除消息队列");
}
*/
return 0;
}