第二十六章 system v消息队列(二)
msgsnd
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
作用:
把一条消息添加到消息队列中
参数:
msqid : 由msgget函数返回的消息队列标识
msgp :是一个指针,指针指向准备发送的消息
msgsz :是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgflg :控制着当前消息队列或到达系统上限时将要发生的事情
IPC_NOWAIT表示队列满不等待,返回EAGAIN错误
0 表示队列满阻塞
返回值:
成功 : 0
失败 : -1
msgbuf
消息结构在两方面受制约:
- 它必须小于系统规定的上限值(MSGMAX)
- 它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.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 const *argv[])
{
if(argc != 3)
{
fprintf(stderr, "Usage : %s <bytes> <type>\n",argv[0]);
exit(EXIT_FAILURE);
}
int len = atoi(argv[1]);
int type = atoi(argv[2]);
int msgid;
msgid = msgget(1234,0);
if(msgid == -1)
ERR_EXIT("msgget");
printf("msget success, msgid=%d\n!",msgid);
struct msgbuf* ptr;
ptr = (struct msgbuf*)malloc(sizeof(long)+len);
ptr->mtype = type;
// =MSGMNB 阻塞
// >MSGMNB Invalid argument
// if(msgsnd(msgid, ptr, len, 0) < 0)
// =MSGMNB Resource temporarily unavailable
// >MSGMNB Invalid argument
if(msgsnd(msgid, ptr, len, IPC_NOWAIT) < 0)
ERR_EXIT("msgsnd");
free(ptr);
return 0;
}
msgrcv
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
作用:
从消息队列接受消息
参数:
msqid : 由msgget函数返回的消息队列标识
msgp :是一个指针,指针指向准备接收的消息
msgsz :是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
msgtyp :它可以实现接收优先级的简单形式
=0 : 返回队列第一条消息
>0 : 返回队列第一条类型等于msgtype的消息
<0 : 返回队列第一条类型小于等于msgtype绝对值的消息
>0 && msgflg=MSC_EXCEPT 接收类型不等于msgtype的第一条消息
msgflg :控制着队列中没有相应类型的消息可提供接收时将要发生的事
IPC_NOWAIT表示队列满不等待,返回EAGAIN错误
MSG_NOERROR 消息大小超过msgsz时被截断
0 表示队列满阻塞
返回值:
成功 : 返回实际放到接收缓冲区里的字符个数
失败 : -1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.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 */
};
#define MSGMAX 8192
int main(int argc, char* argv[])
{
int flag = 0;
int type = 0;
int opt;
while(1)
{
opt = getopt(argc, argv, "nt:");
if(opt == '?')
exit(EXIT_FAILURE);
if(opt == -1)
break;
switch (opt)
{
case 'n':
flag |= IPC_NOWAIT;
break;
case 't':
type = atoi(optarg);
break;
}
}
int msgid;
msgid = msgget(1234,0);
if(msgid == -1)
ERR_EXIT("msgget");
printf("msget success, msgid=%d\n",msgid);
struct msgbuf* ptr;
ptr = (struct msgbuf*)malloc(sizeof(long) + MSGMAX);
ptr->mtype = type;
int nRec = 0;
if( (nRec = msgrcv(msgid, ptr, MSGMAX, type, flag)) < 0)
ERR_EXIT("msgsnd");
printf("read %d bytes type = %ld\n", nRec, ptr->mtype);
free(ptr);
return 0;
}
第二十六章 system v消息队列(二)的更多相关文章
- 第二十五章 system v消息队列(一)
IPC对象的持续性 随进程持续 :一直存在直到打开的最后一个进程结束.(如pipe和FIFO) 随内核持续 :一直存在直到内核自举(内核自举就是把主引导记录加载到内存,并跳转执行这段内存)或显示删除( ...
- 第6章 System V消息队列
6.1 概述 System V消息队列在内核中是list存放的,头结点中有2个指针msg_first 和msg_last.其中每个节点包含:下个节点地址的指针.类型.长度.数据等. 6.2 函数 6. ...
- linux网络编程之system v消息队列(二)
今天继续学习system v消息队列,主要是学习两个函数的使用,开始进入正题: 下面则开始用代码来使用一下该发送函数: 在运行之前,先查看一下1234消息队列是否已经创建: 用上次编写的查看消息队列状 ...
- 第二十七章 system v消息队列(三)
消息队列实现回射客户/服务器 msg_srv.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...
- 第二十九章 System V共享内存
共享内存数据结构 共享内存函数 shmget int shmget(key_t key, size_t size, int shmflg); 功能: 用于创建共享内存 参数: key : 这个共享内存 ...
- 进程间通信 System V 消息队列
1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_ ...
- Linux进程通信之System V消息队列
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...
- 利用System V消息队列实现回射客户/服务器
一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并 ...
- UNIX环境高级编程——system V消息队列
unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的. 消息队列(也叫报文队列)客服了这些缺点: 消息队列就是一个消息的链表. 可以把消 ...
随机推荐
- 05-padding
padding padding:内边距,内容到边框的距离 而且,padding是有背景颜色的.background-color属性将填充所有border以内的区域(不包括border) padding ...
- poll(2) 源码分析
poll(2) poll(2) 系统调用的功能和 select(2) 类似:等待一个文件集合中的文件描述符就绪进行I/O操作. 使用 实现 select(2) 的局限性: 关注的文件描述符集合大小最大 ...
- redis mysql 连接池 之 golang 实现
1 mysql 连接池代码 package lib import ( "database/sql" "fmt" "strconv" &quo ...
- JDBC访问数据库的基本步骤
加载驱动 通过DriverManager对象获取连接对象Connection 通过连接对象获取会话 通过会话进行数据的增删改查,封装对象 关闭资源
- 如何去除CFormView的Scrollbar
第一种方法: 重载 OnSize(UINT nType, int cx, int cy) 在CFormView::OnSize(nType, cx, cy)下面添加一句 ShowScrollBar(S ...
- .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础 -2
上节中,我们初步的介绍了一下NetCore的一些基础知识,为了控制篇幅(其实也是因为偷懒),我将NetCore 基础分为两部分来写. 0.WebAPI 项目的建立 1..NetCore 项目执行(加载 ...
- c语言程序设计2
c语言秋季作业2 问题 答案 这个作业属于哪个课程 C语言程序设计Ⅰ 这个作业要求在哪里 [c语言博客作业02](https://edu.cnblogs.com/campus/zswxy/SE2019 ...
- powerCat进行常规tcp端口转发
实战中,我们也会遇到需要我们进行端口转发的情况,比如已经拿下的目标机1是在dmz区,而目标1所在内网的其他目标只能通过目标1去访问,这时候我们就需要端口转发或者代理来进行后渗透.这次就要介绍一个加强版 ...
- PHP get_object_vars 和 get_class_vars
<?php class Girl { public $id = 1; public $name = 'zhy'; } $girl = new Girl(); var_dump(get_class ...
- PHP array_product
1.函数的作用:计算数组元素的乘积 2.函数的参数: @params array 3.例子: <?php $input = [false,true]; print_r(array_product ...