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

2つの問題があります。

  • Linuxでは、メッセージキュー名はで始まる必要/があります。参照してくださいmq_overview(7)

各メッセージキューは、/somenameという形式の名前で識別されます。つまり、最初のスラッシュとそれに続く1つ以上の文字で構成され、スラッシュではないNAME_MAX(つまり、255)文字までのnullで終了する文字列です。

  • MSG_MAX_COUNTシステムの制限を超えている可能性があります。未満(または等しい)である必要があります/proc/sys/fs/mqueue/max_size。参照してくださいmq_open(3)

EINVAL:O_CREATがoflagで指定され、attrはNULLではありませんでしたが、 attr->mq_maxmsgまたはattr->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 に答える