2016-04-29 17 views
0

現在、POSIXメッセージキューを使用して最小限のIPCを実行しています。私はコマンドとしてuint8_tのものを渡すだけのパイプと長さが最大128文字の文字列を渡すパイプを持っています。コマンドパイプが正常に動作しています。しかし、stringpipeは常に私にエラー番号90を与えます。これはmessage too longを意味します。私はこの問題を示す最小限の例を書いています(注意してください:私はそれを最小限に抑えていますので、受信時にエラー以外のエラー処理はありません)。POSIXメッセージキューerrno90が長すぎます

#include <fcntl.h> 
#include <sys/stat.h> 
#include <mqueue.h> 
#include <errno.h> 
#include <time.h> 
#include <string.h> 
#include <stdio.h> 

int msg_size = 128; 

int send() 
{ 
    struct mq_attr attr = {0, 10, msg_size + 1, 0}; 
    mqd_t mq = mq_open("/test", O_RDWR | O_CREAT, 00644, &attr); 
    char msg[msg_size] = {0}; 
    strncpy(msg, "this_is_a_test", msg_size); 
    mq_send(mq, msg, msg_size, 0); 
} 

int recv() 
{ 
    struct mq_attr attr = {0, 10, msg_size + 1, 0}; 
    mqd_t mq = mq_open("/test", O_RDWR | O_CREAT, 00644, &attr); 
    char msg[msg_size] = {0}; 
    int res = mq_receive(mq, msg, msg_size, NULL); 
    if (res == -1) 
    { 
     printf("Errno: %d\n", errno); 
    } 
    else 
    { 
     printf("Message: %s\n", msg); 
    } 
} 

int main() 
{ 
    send(); 
    recv(); 
    return 0; 
} 

コンパイルと:

g++ -o mq mq.c -lrt 
+0

なぜC++コードがないときにC++コンパイラでコンパイルするのですか? 'gcc'を使って提案してください。コンパイルするときは、常にすべての警告を有効にしてください。 'gcc' /' g ++ 'を最低限使用してください:' -Wall -Wextra -pedantic'私は '-Wconversion -std = gnu99'も使います。ポストされたコードの場合、コンパイラは多くの警告メッセージを出力します。これらの警告を修正してください。 – user3629249

+0

1)メッセージキューは、そのキューを使用するプロセスの数にかかわらず、1回だけ開く必要があります。 2) 'struct mq_attr'の実際のフィールドリストは実装に依存するので、初期化子を使うことはできません。フィールド名で各フィールドを設定します。' mset(&attr、 '\ 0'、sizeof(attr)) ; attr.mq_maxmsg = 300; attr.mq_msgsize = MSG_SIZE; attr.mq_flags = 0; ' – user3629249

答えて

1

あなたがthe mq_receive manual pageを読めば、あなたはEMSGSIZE

msg_lenを意味するメッセージキュー

mq_msgsize属性より 少なかったことがわかりますでしょう

[重点鉱山]

そして、それは本当だが、あなたはmsg_size + 1mq_msgsize属性を設定して、あなたはmq_msgsize属性よりも1小さいmsg_sizeを受けます。

属性を設定するときには、+1は不要です。削除するだけです。

0

次のコード

  1. にきれいに実際にあなたがすでに作成/dev/mqueueデバイスを持っている必要があります
  2. を作品
  3. をコンパイルします。
  4. ローカル関数名に既知のシステム関数名を使用しないでください。
  5. perror()を使用すると、エラーメッセージが正しく出力されます。注:出力は自動的にmq_receive()
  6. ノートへの呼び出しで(size_t)attr.mq_msgsizeの使用のみmqd_t mqdesstruct mq_attr変数がファイルにグローバルでmq_open()
  7. 一度ノートを呼び出す必要が errno
  8. ノートに関連するシステムメッセージが含まれますスペースはすべての機能がそれらを見ることができるようにします。別の方法として、パラメータとして渡すこともできます。 MSG_SIZEはだけなので、それがスタック上にもファイルグローバル空間上のスペースを消費しない#defineを介して定義され
  9. ノートでは、各機能ではなく、一度定義する必要があり、コードで使用されていない
  10. ヘッダファイルべき含まれない。
  11. 音符attrは、個々のフィールドにのみメッセージの実際の長さは(mq_sendの呼び出しで指定され
  12. 音符)を設定する前に、すべての0x00にクリアされるので、何ゴミが送信されない/
を受け

と今のコード

#include <fcntl.h> 
#include <sys/stat.h> 
#include <mqueue.h> // mq_open(), mq_send(), mq_receive() 

//#include <errno.h> 
//#include <time.h> 
#include <string.h> // strncpy(), strlen() 

#include <stdio.h> // printf(), perror() 
#include <stdlib.h> // exit(), EXIT_FAILURE 

#define MSG_SIZE (128) 

static mqd_t mqdes = -1; 
static struct mq_attr attr; 

void sendQueue() 
{ 
    char msg[ MSG_SIZE ] = {0}; 
    strncpy(msg, "this_is_a_test", MSG_SIZE); 
    if(-1 == mq_send(mqdes, msg, strlen(msg), 5)) 
    { 
     perror("mq_send failed"); 
     exit(EXIT_FAILURE); 
    } 

    else 
    { 
     printf("%s\n", "msg sent successfully"); 
    } 
} 

void recvQueue() 
{ 
    char msg[ MSG_SIZE ] = {0}; 

    ssize_t res = mq_receive(mqdes, msg, (size_t)attr.mq_msgsize, NULL); 
    if (res == -1) 
    { 
     perror("mq_receive failed"); 
    } 

    else 
    { 
     printf("Message: %s\n", msg); 
    } 
} 

int main(void) 
{ 
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 

    memset(&attr, 0x00, sizeof(struct mq_attr)); 
    attr.mq_maxmsg = 3; 
    attr.mq_msgsize = MSG_SIZE; 
    attr.mq_flags = 0; 
    attr.mq_curmsgs = 0; 

    char *queueName = "/test"; 

    mqdes = mq_open(queueName, O_RDWR|O_CREAT, mode, &attr); 
    if(-1 == mqdes) 
    { 
     perror("mq_open failed"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, mq_open successful 


    sendQueue(); 
    recvQueue(); 
    return 0; 
} 
関連する問題