2010-11-25 13 views
1

メッセージキューを使用して2つのプロセス間で通信する必要があります。 1つのプロセスが別のプロセスに要求を送信し、他のプロセスが応答を送信します。メッセージキューを使用したプロセス間でのメッセージの受け渡し

たとえば、要求の1つは、プロセスによって開かれたすべてのファイル名を一覧表示することです。私は上記の設計に問題がデータを指しているのchar *ポインタを変更しているlegthファイル名として異なっているが、構造体の大きさは常に一定であるため、受信機は、すべてのrecevingされていないということだと思います

#define LIST_NAMES 1 
#define LIST_FILE_NAMES_RESP 2 

struct sFileStruct { 
    unsigned int uiCommand; 
    unsigned long ulNoOfBytes; // Number of bytes to be parsed in cha* pointer below 
    char*   pRecvData; // file names packed here in response. 
}; 


sFileStruct inData; 
// I am filling the data. 
int inSize = sizeof(inData); 

mq_send(m_qSendDesc, (char*)&inData, inSize, inPriority); 

として界面構造をしましたchar *ポインタにアクセスしている間、データとレシーバがクラッシュしています。

1つのmq_sendで完全なデータを送信したいが、静的配列を構造体内に入れたくない。私たちがこれを達成できるメッセージキューを使用する他の方法はありますか?

入力してください。 ありがとう

+1

覚えている:あなたのコードをインデントする場合は、適切にフォーマットされます! –

答えて

1

mq_send()に、charバッファが割り当てられたラッパーを作成できます。

送信するすべてのメッセージはこのバッファにシリアル化され、適切な長さ(sizeof(int)+ sizeof(long)+ strlen(pRecvData))を持つmq_sendに渡されます。

受信者はこのデータを読み取り、それをsFileStructにデシリアライズします。

IMHO char *の代わりにstd :: stringを使用する方が良いでしょう。

サンプルコード(テストされていません):

class MQWrapper 
{ 
    std::string m_strBuffer; 
public: 
    int Send(const sFileStruct& sfs) 
    { 
     m_strBuffer.clear(); 
     m_strBuffer.append(static_cast<const char*> & sfs.uiCommand, sizeof(sfs.uiCommand)); 
     m_strBuffer.append(static_cast<const char*> & sfs.ulNoOfBytes, sizeof(sfs.ulNoOfBytes)); 
     m_strBuffer.append(sfs.pRecvData); // only if it's zero-terminated string!!! 

     return mq_send(m_qSendDesc, m_strBuffer.c_str(), m_strBuffer.length(), inPriority); 
    } 


    char m_receiveBUffer[ BUFFER_SIZE ]; 

    int Receive(sFileStruct& sfs) 
    { 
     int res = mq_receive(m_qSendDesc, receiveBUffer, BUFFER, outPriority); 
     if(res < 0) 
      return res; 
     if(res < sizeof(int) + sizeof(long)) 
      return -1000; // malformed message 
     sfs.uiCommand = * (static_cast<unsigned int*> (m_receiveBUffer[0])); 
     sfs.ulNoOfBytes = * (static_cast<long*> (m_receiveBUffer[ sizeof(int) ])); 

     // I don't really use this style in my work and not sure how to use it 
     // str::string would be much easier 
     int stringLen = res - sizeof(int) - sizeof(long); 
     sfs.pRecvData = new char [ stringLen + 1 ]; // you have to delete [] it later 
     if(stringLen > 0) 
      strcpy(sfs.pRecvData, receiveBUffer + sizeof(int) + sizeof(long), stringLen); 
     ss.pRecvData[ stringLen ] = '\0'; // null terminator 
     return 0; 
    } 
}; 
+0

ありがとうございました。私はこれを使用しようとしています。受信側で上記のパックされた情報を解析する方法を提供することは可能ですか? – venkysmarty

+0

@ user519882私はReceive関数のいくつかの例も紹介しました。正直言って、私はstd :: stringのようなstlのものを使用しないのが本当に心地よいとは言えませんが、それでもあなたの問題を解決するヒントを与えることができます。 –

0

mq_sendの2番目のパラメータはconst char *値であってはなりませんか?しかし、あなたはカスタム記述された構造体を渡しています。私はシリアライズしたり、構造体をconst char *に変換したり、strlenを使ってその長さを取得したり、これら2つの値を2番目と3番目の引数としてmq_sendに渡したりするコードを記述します。

+0

申し訳ありませんが、それは間違って言及されました、それは今編集されましたmq_send(m_qSendDesc、(char *)&inData、inSize、inPriority); – venkysmarty

+0

こんにちは - 構造体をchar *にキャストして変換することはできません。intをchar *に変換しているので変換をコーディングする必要があります。 –

3

送信者プログラムからの使用にのみ使用できるポインタにアクセスできないため、受信者がクラッシュしています。実際のデータをポインタではなくメッセージキューに送る必要があります。

+0

あなたは構造でこれをどのように達成するのか教えてください。 – venkysmarty

+0

Numenorと同じように、2つの符号なしの数字をメッセージのヘッダーにし、ポインタの代わりに実際の文字データを続けます。 – kdo

関連する問題