【问题标题】:How to check if a message is empty如何检查消息是否为空
【发布时间】:2017-10-17 13:29:07
【问题描述】:

所以我一直在这样做一整天,并没有弄明白。我需要检查是否有空消息传递给接收方或服务器,然后取消链接队列。 这就是我所拥有的:

while((c=getopt(argc, argv, ":q:"))!=-1){
    switch(c){
        case 'q':
            q = 1;
            Q = optarg;
            break;
    }
}
int oprimek_vrsta = -1;
char *msg = malloc(maxmsg_len + 1);

if(q != 0){
    oprimek_vrsta = mq_open(Q, O_RDWR|O_CREAT|O_EXCL, 0660, &lastnosti_vrste);
    if(oprimek_vrsta == -1){
        perror("error creating queue");
        return -1;
    }

    if(mq_getattr(oprimek_vrsta, &lastnosti_vrste) == -1){
        perror("error reading attributes");
        return -1;
    }
    while(loop){
        memset(msg, 0, 4096);
        munmap(msg, 4096);
        msg_len = mq_receive(oprimek_vrsta, msg, maxmsg_len, &priority);
        if(msg_len == -1){
            perror("error reading message");
            loop = 0;
            free(msg);
            mq_close(oprimek_vrsta);
            mq_unlink(Q);
            return -1;
        }else{
            write(1, msg, strlen(msg));
        }
    }
}

【问题讨论】:

  • 如果消息为空,您不会收到msg_len == 0 吗?
  • 您要检查队列是否为空,或者收到的消息是否为空?
  • 我没有得到 0,由于某种原因它是 1,但是如果我输入 1,即使我发送一些东西它也会中断。 @alk 我认为两者都会起作用
  • 如果mq_receive() 返回 1,那么你收到的那一个字节的值是多少?
  • 发送时显示为 0

标签: c linux posix message-queue mq


【解决方案1】:

来自 mq_receive 手册:

mq_receive() removes the oldest message with the highest priority
from the message queue ... If the queue is empty, then, by default, 
mq_receive() blocks until a message becomes available, 
or the call is interrupted by a signal handler.  
If the O_NONBLOCK flag is enabled for the message
queue description, then the call instead fails immediately with the error EAGAIN.

RETURN VALUE: On success, mq_receive() and mq_timedreceive() return the 
number of bytes in the received message; on error, -1 is returned, 
with errno set to indicate the error.

mq_receive 的返回值不是您想要的。您需要检查您收到的消息长度是否为0。

我也强烈建议您阅读this有关 POSIX 消息队列的有用教程。

这是一个工作示例:

#include <stdio.h>
#include <mqueue.h>
#include <stdlib.h>
#include <string.h> /* memset */
#include <unistd.h> /* close */
#include <sys/mman.h>

#define QUEUE_NAME "/test"
#define MAX_MSG_LEN 100

int main(int argc, char **argv)
{
    int q;
    char* Q;
    char c;
    int loop = 1;
    int msg_len;

    struct mq_attr lastnosti_vrste;

    lastnosti_vrste.mq_flags = 0;
    lastnosti_vrste.mq_maxmsg = 10;
    lastnosti_vrste.mq_msgsize = 100;
    lastnosti_vrste.mq_curmsgs = 0; 


    while((c=getopt(argc, argv, "q:")) != -1)
    {
        switch(c)
        {
            case 'q':
                mq_unlink(Q);
                q = 1;
                Q = QUEUE_NAME;
            break;
        }
    }

    int oprimek_vrsta = -1;
    char *msg = malloc(MAX_MSG_LEN + 1);

    if(q != 0)
    {
        oprimek_vrsta = mq_open(Q, O_RDWR|O_CREAT|O_EXCL, 0660, &lastnosti_vrste);
        if(oprimek_vrsta == -1){
            perror("error creating queue");
            return -1;
        }

        if(mq_getattr(oprimek_vrsta, &lastnosti_vrste) == -1){
            perror("error reading attributes");
            return -1;
        }
        while(loop)
        {

            memset(msg, 0, 4096);
            munmap(msg, 4096);
            msg_len = mq_timedreceive(oprimek_vrsta, msg, MAX_MSG_LEN, 0);
            if(strlen(msg) == 0)
            {
                perror("error reading message");
                loop = 0;
                mq_close(oprimek_vrsta);
                mq_unlink(Q);
                return -1;
            }
            else
            {
                write(1, msg, strlen(msg));
            }
        }

        free(msg);
    }

return 0;
}

【讨论】:

  • "if(strlen(msg) == 0) ..." 所以如果收到的第一个char'\0'你认为错误。为什么?在 msg` 上使用 strlen() 是假设一个非常具体的用例,即收到了一个“字符串”,但不一定是这种情况。
  • "mq_receive 的返回值不是你要找的" 为什么不呢?因为正如您从文档中引用的那样:“返回值:成功时,mq_receive() 和 mq_timedreceive() 返回接收到的消息中的字节数”。 0 收到的字节表示一条空消息,不是吗?
  • 否则您将如何收到一条空消息? (-1) 返回值显然不起作用
  • mq_receive() 返回值0 怎么样?除了任何非空消息将包含什么(数据类型、字符串、二进制)之外,空消息还会指示什么。
猜你喜欢
  • 2012-09-14
  • 1970-01-01
  • 2017-12-25
  • 2021-10-28
  • 2021-05-15
  • 2021-04-18
  • 1970-01-01
  • 2017-11-15
  • 2020-05-29
相关资源
最近更新 更多