diff --git a/day5/rec_sed/msgque2_sender.c b/day5/rec_sed/msgque2_sender.c new file mode 100644 index 0000000..3a671cc --- /dev/null +++ b/day5/rec_sed/msgque2_sender.c @@ -0,0 +1,90 @@ +#include +#include // 系统数据类型定义 +#include // IPC相关头文件 +#include // 消息队列相关头文件 +#include // 字符串操作 +#include // atol 函数 + +// 消息结构体 +typedef struct msg_ +{ + long mType; // 消息类型,必须是 long ,必须在第一个位置 + char content[100]; // 消息内容,需要小于消息队列的限制值(8192) + char title[32]; // 消息标题 + +} MSG; + +// msgget 函数用于创建消息队列,参数1是键值,参数2是权限 +int main(int argc, char *argv[]) +{ + // 判断参数个数 + if (argc != 4) + { + printf("Usage: %s \n", argv[0]); + return 1; + } + + key_t key = ftok("/", 200); // 获取消息队列的键值 + + // msgget 函数用于创建消息队列,参数1是键值,参数2是权限 + // 返回值是消息队列的标识符,类似于文件描述符 + // IPC_CREAT 表示如果消息队列不存在则创建,如果存在则打开 + // 0644 表示权限,类似于文件权限,表示所有者可读写,其他人只读 + int msgqid = msgget(key, IPC_CREAT | 0666); // 创建消息队列 + if (msgqid == -1) + { + perror("msgget"); + return 1; + } + + // msgqid 只要不是 -1 就表示创建成功 + printf("msgqid = %d\n", msgqid); // 打印消息队列标识符 + + // 发送消息 + // 1 表示类型,表示发送消息的类型,必须大于 0 + // MSG msg1 = {1, "测试消息队列的发送函数 msgsnd", "测试"}; // 消息内容 + + MSG msg1; + msg1.mType = atol(argv[1]); // 消息类型 + strcpy(msg1.content, argv[2]); // 消息内容 + strcpy(msg1.title, argv[3]); // 消息标题 + + // 参数 4 表示阻塞,如果消息队列满了,发送消息的进程会阻塞 + // 非阻塞的话,消息队列满了,发送消息的进程会立即返回,不会阻塞 + // int ret = msgsnd(msgqid, &msg1, sizeof(msg1.content), 0); // 发送消息 + int ret = msgsnd(msgqid, &msg1, sizeof(msg1.content) + sizeof(msg1.title), IPC_NOWAIT); // 发送消息 + if (ret == -1) + { + perror("msgsnd"); + return 1; + } + printf("msg1 发送成功\n"); + + return 0; +} + +/* + ipc: inter process communication 进程间通信 + + ipcs -q // 查看消息队列 + ipcrm -q <msqid> // 删除消息队列 +*/ + +/* + ipc 通信方式 + 1. 管道 + 2. 消息队列 + 3. 共享内存 + 4. 信号量 + 5. 套接字 +*/ + +/* + 使用说明,配合 msgque3_receiver.c (receiver) 使用: + 1. 编译 msgque2_sender.c (sender) 和 msgque3_receiver.c (receiver) + 2. 运行 msgque2_sender.c (sender) 发送消息 + 3. 运行 msgque3_receiver.c (receiver) 接收消息 + + ipcs -q 可以查看消息队列 + ipcrm -q <msqid> 可以删除消息队列 +*/ \ No newline at end of file diff --git a/day5/rec_sed/msgque3_receiver.c b/day5/rec_sed/msgque3_receiver.c new file mode 100644 index 0000000..7c953b2 --- /dev/null +++ b/day5/rec_sed/msgque3_receiver.c @@ -0,0 +1,62 @@ +#include <stdio.h> +#include <sys/types.h> // 系统数据类型定义 +#include <sys/ipc.h> // IPC相关头文件 +#include <sys/msg.h> // 消息队列相关头文件 +#include <string.h> // 字符串操作 +#include <stdlib.h> // atol 函数 + +// 消息结构体 +typedef struct msg_ +{ + long mType; // 消息类型,必须是 long ,必须在第一个位置 + char content[100]; // 消息内容,需要小于消息队列的限制值(8192) + char title[32]; // 消息标题 + +} MSG; + +// msgget 函数用于创建消息队列,参数1是键值,参数2是权限 +int main(int argc, char *argv[]) +{ + // 参数个数判断 + if (argc != 2) + { + printf("Usage: %s <type>\n", argv[0]); + return 1; + } + + key_t key = ftok("/", 200); // 获取消息队列的键值 + + int msgqid = msgget(key, IPC_CREAT | 0666); // 创建消息队列 + if (msgqid == -1) + { + perror("msgget"); + return 1; + } + + // 接收消息 + MSG msg; // 消息结构体 + long mtype = atol(argv[1]); // 消息类型 + + // 最后参数 0 表示阻塞,如果消息队列为空,接收消息的进程会阻塞 + ssize_t len = msgrcv(msgqid, &msg, sizeof(msg.content) + sizeof(msg.title), mtype, 0); // 接收消息 + printf("接收到的数据(%ld),\n类型(%ld),\n内容(%s),\n标题(%s)\n", len, msg.mType, msg.content, msg.title); // 打印消息 + + return 0; +} + +/* + 使用说明,配合 msgque2_sender.c (sender) 使用: + 1. 编译 msgque2_sender.c (sender) 和 msgque3_receiver.c (receiver) + 2. 运行 msgque2_sender.c (sender) 发送消息 + 3. 运行 msgque3_receiver.c (receiver) 接收消息 + + 使用时: + ./receiver <type> + type 是消息类型,必须是整数,必须大于 0 + 当 type 为 -5 时,接收到的消息是类型小于 5 的消息 + 当 type 为 1 时,接收到的消息是类型为 1 的消息 + 当 type 为 0 时,接收到的消息是类型为最小的消息 + + ipcs -q 可以查看消息队列 + ipcrm -q <msqid> 可以删除消息队列 +*/ \ No newline at end of file diff --git a/day5/rec_sed/receiver b/day5/rec_sed/receiver new file mode 100755 index 0000000..f1a0275 Binary files /dev/null and b/day5/rec_sed/receiver differ diff --git a/day5/rec_sed/send b/day5/rec_sed/send new file mode 100755 index 0000000..ab35279 Binary files /dev/null and b/day5/rec_sed/send differ