2010-11-25 6 views
1

메시지 대기열을 사용하는 두 프로세스간에 통신 할 수있는 자격이 있습니다. 한 프로세스가 요청을 다른 프로세스로 보내고 다른 프로세스가 응답을 보냅니다.메시지 대기열을 사용하는 프로세스간에 메시지 전달

예를 들어 요청 중 하나는 프로세스에서 열려있는 모든 파일 이름을 나열합니다. 나는 위의 디자인 문제가 문자를 변화 legth 파일 이름으로 * 데이터에 대한 포인터를 가리키는은 다르지만, 구조의 크기가 항상 일정하다는 생각

#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 * 포인터에 액세스하는 동안 데이터와 수신자가 충돌합니다.

하나의 mq_send에서 전체 데이터를 보내려고하며 구조 내부에 정적 배열을 갖고 싶지 않습니다. 우리가 이것을 달성 할 수있는 메시지 대기열을 사용하는 다른 방법이 있습니까?

의견을 제공해주세요. 감사합니다.

+1

기억하십시오 : 당신은 당신의 코드를 들여 쓰기 경우 제대로 포맷됩니다! –

답변

1

mq_send() 이상의 문자 버퍼가 할당 된 래퍼를 만들 수 있습니다.

보내는 메시지는 모두이 버퍼로 직렬화되며 적절한 길이 (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 수신 기능에 대한 몇 가지 예를 게시했습니다. 솔직히 말해서 나는 std :: string과 같은 stl을 사용하지 않는 것이 정말 기분이 좋지 않지만 여전히 문제를 해결하는 방법에 대한 힌트를 줄 수 있습니다. –

0

mq_send의 두 번째 매개 변수가 const char * 값이 아니어야합니까? 하지만 사용자 정의 작성 구조체를 전달하고 있습니다. serialize하거나 구조체를 const char *로 변환 한 다음 strlen을 사용하여 길이를 구하고이 두 값을 mq_send의 두 번째 및 세 번째 인수로 전달합니다.

+0

죄송합니다. 질문에 잘못 언급되었지만 지금 편집되었습니다. mq_send (m_qSendDesc, (char *) & inData, inSize, inPriority); – venkysmarty

+0

안녕하세요 - 구조체를 char *로 변환하여 변환 할 수는 없습니다. int를 char *로 변환하기 때문에 변환을 코딩해야합니다. –

3

송신자 프로그램에서만 사용할 수있는 포인터에 액세스 할 수 없어 수신기가 충돌합니다. 실제 데이터를 포인터가 아닌 메시지 큐에 보내야합니다.

+0

구조로 어떻게 이것을 달성 할 수 있습니까? – venkysmarty

+0

정확하게 Numenor가 말했듯이 - 두 개의 서명되지 않은 숫자를 메시지의 헤더로 만든 다음 포인터 대신 실제 문자 데이터를 따르십시오. – kdo

관련 문제