2

我正在尝试编写一些使用 linux 消息的客户端-服务器应用程序示例。这是我的代码:

#include <mqueue.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#define MSG_SIZE 4096
#define MSG_MAX_COUNT 1024
#define MSG_TYPE_TO_UPPER 0
#define MSG_TYPE_EXIT 1
#define MQ_NAME "msg_queue"

namespace {
    int str_toupper(char *str)
    {
        int len = 0;
        for(; str[len]; ++len) {
            str[len] = toupper(str[len]);
        }
        return len;
    }
}

int main(int argc, char** argv)
{
    if(argc != 2) {
        fprintf(stderr, "Usage: msg_queue (client|server)\n");
        exit(EXIT_FAILURE);
    }

    struct mq_attr attr;    // MQueue attributes
    mqd_t mqd;      // MQueue descriptor
    char buf[MSG_SIZE]; // Msg buffer
    unsigned int type;  // Msg type(priority)

    // Set up MQueue attributes
    attr.mq_maxmsg = MSG_MAX_COUNT;
    attr.mq_msgsize = MSG_SIZE;
    attr.mq_flags = 0;
    attr.mq_curmsgs = 0;

    mqd = mq_open(MQ_NAME, O_RDWR | O_CREAT, 0664, &attr);
    if(mqd == -1) {
        fprintf(stderr, "mq_open() failed for \""MQ_NAME"\": %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    if(strcmp(argv[1], "server") == 0) {
        while(mq_receive (mqd, buf, MSG_SIZE, &type) != -1) {
            if(type == MSG_TYPE_EXIT) {
                mq_unlink(MQ_NAME);
                mq_close(mqd);
                break;
            } else if(type == MSG_TYPE_TO_UPPER) {
                int len = str_toupper(buf);
                if(mq_send (mqd, buf, len, MSG_TYPE_TO_UPPER) == -1) {
                    fprintf(stderr, "Server: mq_send() failed: %s", strerror(errno));
                }
            }
        }
    } else if(strcmp(argv[1], "client") == 0) {
        while(1) {
            printf("Input a message: <type>(0 - TO_UPPER, 1 - EXIT) <message>\n");
            scanf("%u %s", &type, buf);

            if(mq_send (mqd, buf, strlen(buf), type) == -1) {
                fprintf(stderr, "Client: mq_send() failed: %s", strerror(errno));
            }

            if(type == MSG_TYPE_TO_UPPER) {
                if(mq_receive (mqd, buf, MSG_SIZE, &type) == -1) {
                    fprintf(stderr, "Client: mq_receive() failed: %s", strerror(errno));
                }
                printf("\"%s\" received\n", buf);
            } else if(type == MSG_TYPE_EXIT) {
                mq_unlink(MQ_NAME);
                mq_close(mqd);
                break;
            }
        }
    } else {
        fprintf(stderr, "Usage: msg_queue (client|server)\n");
        exit(EXIT_FAILURE);
    }
    return 0;
}

我的错误是什么?它总是从第 47 行打印错误 -fprintf(stderr, "mq_open() failed for \""MQ_NAME"\": %s\n", strerror(errno));带有errno = EINVAL.

4

1 回答 1

2

我看到两个问题:

  • 在 Linux 上,您的消息队列名称必须以 a 开头。/mq_overview(7)

每个消息队列由 /somename 形式的名称标识;即,最多 NAME_MAX(即 255)个字符的以 null 结尾的字符串,由一个初始斜杠组成,后跟一个或多个字符,其中没有一个是斜杠。

  • MSG_MAX_COUNT很可能超出您的系统限制。它必须小于(或等于)/proc/sys/fs/mqueue/max_size。见mq_open(3)

EINVAL: 在 oflag 中指定了 O_CREAT,并且 attr 不是 NULL,但是 attr->mq_maxmsgorattr->mq_msqsize是无效的。这两个字段都必须大于零。在非特权进程(没有 CAP_SYS_RESOURCE 能力)中,attr->mq_maxmsg必须小于或等于 msg_max 限制,并且attr->mq_msgsize必须小于或等于 msgsize_max 限制。此外,即使在特权进程中,attr->mq_maxmsg也不能超过 HARD_MAX 限制。(有关这些限制的详细信息,请参阅 mq_overview(7)。)

另一个限制可能没问题,但您也应该验证它。

于 2012-05-19T11:34:46.280 回答