首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >mq_receive:消息太长

mq_receive:消息太长
EN

Stack Overflow用户
提问于 2011-04-12 02:37:05
回答 4查看 26.3K关注 0票数 11

我正在使用队列实现两个进程之间的通信。问题是,当我调用函数mq_receive时,我得到这样的错误:消息太长。

我做了以下工作:

代码语言:javascript
运行
复制
struct mq_attr attr;

long size = attr.mq_msgsize;
.... // initializing the queue "/gateway"

int rc = mq_receive(gateway, buffer, size, &prio);

如果我打印大小值,我会得到size=1,而当我打印相同大小但来自另一个程序(通过相同的机制获得)时,我会得到一些不太长的整数( -1217186280 )...

当error?....so = 1的时候我该如何解决这个问题,我相信说“消息太长”是对的,但是为什么是1呢?

另外,我还试着把:

代码语言:javascript
运行
复制
int rc = mq_receive(gateway, buffer, sizeof(buffer), &prio);

但是没有结果。

EN

回答 4

Stack Overflow用户

发布于 2011-10-26 21:47:04

看起来你需要更仔细地阅读文档。当你调用mq_receive时,你应该传递目标缓冲区的大小。此大小必须大于队列的mq_msgsize属性。此外,队列属性初始化中似乎有一个错误,这使得正确的mq_receive调用变得不可能。下面是标准消息队列会话:

  1. Fill mq_attr struct (doc):

struct mq_attr attr;attr.mq_flags = 0;attr.mq_maxmsg = 10;attr.mq_msgsize = 33;attr.mq_curmsgs = 0;

  • 在主进程(doc)中使用mq_open创建队列:

mqd_t队列= mq_open(qname,O_CREAT|O_RDWR,0644,&attr);写入器进程打开写入队列中的

mqd_t队列= mq_open(qname,O_WRONLY);

然后发一些短信。文本长度必须小于队列的mq_msgsize属性(doc):

mq_send( queue,"some message",strlen("some message")+1,1);

  • In reader process打开队列读取:

mqd_t队列= mq_open(qname,O_RDONLY);

然后分配缓冲区并接收报文。buffer *的大小必须大于队列的mq_msgsize属性。这里我们创建一个50字节的buffer,同时使用mq_msgsize == 33 (doc):

字符队列;int iret =mq_receive(rcvmsg50,rcvmsg,50,NULL);

还要记住,对于打印long,您应该使用%ld而不是%d

票数 22
EN

Stack Overflow用户

发布于 2011-10-21 17:29:31

在调试实时POSIX队列时,您应该从一个可以正常工作的示例程序开始,然后继续下去。运行示例程序后,只需确保您自己的代码遵循所有步骤即可。

以下程序已在Ubuntu 11.04下测试成功:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <mqueue.h>

#define MQNAME "/pax"
#define MQMESG "Hello there!"

static mqd_t serverUp (void) {
    int rc;
    mqd_t svrHndl;
    struct mq_attr mqAttr;

    printf ("Bringing up server.\n");
    rc = mq_unlink (MQNAME);
    if (rc < 0) {
        printf ("   Warning %d (%s) on server mq_unlink.\n",
            errno, strerror (errno));
    }

    mqAttr.mq_maxmsg = 10;
    mqAttr.mq_msgsize = 1024;
    svrHndl = mq_open (MQNAME, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR, &mqAttr);
    if (svrHndl < 0) {
        printf ("   Error %d (%s) on server mq_open.\n",
            errno, strerror (errno));
        exit (1);
    }
    printf ("   Server opened mqd_t of %d.\n", svrHndl);
    return svrHndl;
}

static void serverReceive (mqd_t svrHndl) {
    int rc;
    char buffer[2048];
    printf ("Server receiving on mqd_t %d.\n", svrHndl);
    rc = mq_receive (svrHndl, buffer, sizeof (buffer), NULL);
    if (rc < 0) {
        printf ("   Error %d (%s) on server mq_receive.\n",
            errno, strerror (errno));
        exit (1);
    }
    printf ("   Received [%s].\n", buffer);
}

static void serverDown (mqd_t svrHndl) {
    printf ("Bringing down server with mqd_t %d.\n", svrHndl);
    mq_close (svrHndl);
}
static void clientSend (void) {
    mqd_t cliHndl;
    int rc;
    printf ("Client sending.\n");
    cliHndl = mq_open (MQNAME, O_RDWR);
    if (cliHndl < 0) {
        printf ("   Error %d (%s) on client mq_open.\n",
            errno, strerror (errno));
        exit (1);
    }
    printf ("   Client opened mqd_t of %d.\n", cliHndl);

    rc = mq_send (cliHndl, MQMESG, sizeof (MQMESG), 1);
    if (rc < 0) {
        printf ("   Error %d (%s) on client mq_send.\n",
            errno, strerror (errno));
        exit (1);
    }

    mq_close (cliHndl);
}

int main (void) {
    mqd_t svrHndl;

    svrHndl = serverUp ();
    clientSend ();
    serverReceive (svrHndl);
    serverDown (svrHndl);

    return 0;
}

我的系统上的输出是:

代码语言:javascript
运行
复制
Bringing up server.
   Server opened mqd_t of 3.
Client sending.
   Client opened mqd_t of 4.
Server receiving on mqd_t 3.
   Received [Hello there!].
Bringing down server with mqd_t 3.
票数 9
EN

Stack Overflow用户

发布于 2014-01-15 08:54:58

在再次运行您的程序之前,不要忘记取消消息队列的链接。如果不取消链接,它仍将使用旧的消息队列设置。当你用Ctrl+C结束你的程序时,就会发生这种情况。我认为把下面的代码放在程序的开头是个好主意:

代码语言:javascript
运行
复制
if(mq_unlink(QUEUENAME) == 0)
  fprintf(stdout, "Message queue %s removed from system.\n", QUEUENAME);

另一种形式(C++样式),它检查真正的错误(如权限),并忽略队列已经存在或不存在的情况:

代码语言:javascript
运行
复制
int rc = mq_unlink(name.c_str());
if (rc != 0 && errno != ENOENT)
      THROW_ERRNO_EXCEPTION();  

// ENOENT is the status code if the queue doesn't exist, which is not an error
// if you are immediately going to create it.
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5625845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档