【问题标题】:Sending buffer through message queue通过消息队列发送缓冲区
【发布时间】:2012-10-20 10:19:27
【问题描述】:

嗨,我正在编写一个程序,它通过消息队列发送一组字节,就像这样......

#include <sys/msg.h>
#include <stddef.h>

key_t key;
int msqid;
struct pirate_msgbuf pmb = {2, { "L'Olonais", 'S', 80, 10, 12035 } };

key = ftok("/home/beej/somefile", 'b');
msqid = msgget(key, 0666 | IPC_CREAT);

/* stick him on the queue */
msgsnd(msqid, &pmb, sizeof(struct pirate_msgbuf) - sizeof(long), 0);

上面的例子是一个来自beejs网站的简单程序,和我的很像。

然而,我正在做的是发送一条带有这样结构的消息......

struct msg_queue{

    long message_type;
    char * buffer;

}

现在,在我发送我的 msg_queue 之前,我创建了一些替代缓冲区,其中包含各种信息,包括空字符等。现在当我做这样的事情时......

struct msg_queue my_queue;
my_queue.message_type = 1;
my_queue.buffer = "My message";
msgsnd(mysqid, &pmb, sizeof(struct msg_queue) - sizeof(long), 0);

接收指针和读取存储在该字符串中的值没有问题。但是,如果我要做类似的事情...

struct msg_queue my_queue;
my_queue.message_type = 1;
my_queue.buffer = sum_buffer_with_lots_of_weird_values; // of type char *
msgsnd(mysqid, &pmb, sizeof(struct msg_queue) - sizeof(long), 0);

我通过队列传递给其他进程的指针将读取垃圾而不是存储的值。我尝试将我的任意数组设为静态字符 *,但这也无济于事。如何通过队列正确传递缓冲区?谢谢。

【问题讨论】:

  • 嘿,谢谢,我知道进程有自​​己的未共享的内存空间。我只是认为,由于指针 = 数组,至少在大多数情况下,msgsend() 只会发送指向动态分配的内存空间的地址,其中 const char * 字符串将发送内容而是固定长度的数组。我想我唯一的选择是使用固定长度的数组,这让我很沮丧。我认为缓冲区 = malloc(number_of_bytes);将与缓冲区[number_of_bytes]; 相同。

标签: c linux pointers ipc message-queue


【解决方案1】:

您不应该向另一个进程发送指针,它们在另一个进程的地址空间中没有意义(或指向非常不同的东西)。

消息队列不适用于可变长度字符串等无限数据。将指针更改为足够大以容纳最大字符串的固定长度 char 数组,并在写入队列之前将字符串复制到数组中。或者使用其他类型的 IPC,例如域套接字。

【讨论】:

    【解决方案2】:

    消息队列用于进程间通信。 当你在一个进程中 malloc 一些内存时,它只存在于该进程的内存空间中,其他进程无法访问。

    当您发送该指针时,您正在发送一个不可访问的地址空间。它甚至可能导致分段错误。

    一种方法是限制缓冲区大小(如果适用)。

    结构 msg_queue{

    long message_type;
    char buffer[MAX_LEN];
    

    }

    另一种方法是发送 2 次。第一个 msgsnd 发送期望的缓冲区大小。 下一次发送,您使用第一次发送的大小发送 char 数组。 :)

    在接收端,你首先获取大小,然后接收缓冲区。

    其他方法是使用管道或套接字。

    【讨论】:

      【解决方案3】:

      "msgsend()" 只会读取缓冲区中的字节。

      如果其中一个字节恰好是一个指针(指向其他地方的某个字符串或对象)......猜猜看 - 接收者将只获得二进制指针。不是指向的数据。

      您需要做的是将消息的整个内容打包到一个缓冲区中,然后发送该线性缓冲区。

      【讨论】:

      • 所以唯一的办法就是创建一个固定的数组[]。我想我认为指向分配内存的指针与消息缓冲区是一样的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-27
      • 2021-06-05
      • 2013-04-02
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多