2010-11-25 21 views
1

J'ai un besoin d'avoir une communication entre deux processus utilisant des files d'attente de messages. Un processus envoie la demande à un autre processus et un autre processus envoie une réponse.Passer des messages entre processus à l'aide de files d'attente de messages

Par exemple, l'une des demandes est la liste de tous les noms de fichiers ouverts par le processus. J'ai fait la structure d'interface

#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); 

Je pense que problème avec la conception ci-dessus est que les noms de fichiers legth est en train de changer char * pointeur vers les données sont différentes, mais la taille de la structure est toujours constante, de sorte que le récepteur n'est pas receving tous les données et le récepteur se plantent lors de l'accès au pointeur char *.

Je souhaite envoyer des données complètes dans un seul mq_send et ne souhaite pas avoir de matrice statique dans la structure. Existe-t-il un autre moyen d'utiliser les files d'attente de messages?

Veuillez fournir vos entrées. Merci

+1

Rappelez-vous: Si vous indentez votre code, il sera formaté correctement! –

Répondre

1

Vous pouvez créer un encapsuleur sur mq_send() en affectant le buffer char.

Chaque message que vous envoyez sera sérialisé dans ce tampon, puis vous le passerez à mq_send avec length - sizeof (int) + sizeof (long) + strlen (pRecvData).

Le récepteur lira ces données et les désérialisera dans sFileStruct.

À mon humble avis en utilisant std :: string au lieu de char * serait mieux.

Exemple de code (non testé):

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

Merci pour votre suggestion. J'essaie d'utiliser ça. Est-il possible de fournir comment analyser les informations emballées ci-dessus du côté du récepteur. – venkysmarty

+0

@ user519882 J'ai également posté un exemple de fonction de réception. Pour être honnête, je ne me sens pas vraiment à l'aise de ne pas utiliser des trucs stl comme std :: string, mais ça pourrait vous donner une idée de la façon de résoudre votre problème. –

0

Le deuxième paramètre de mq_send ne devrait-il pas être une valeur const char *? Mais vous passez une structure personnalisée. J'écrirais du code pour sérialiser ou transformer la structure, si j'étais vous, en const char *, puis utiliser strlen pour obtenir sa longueur et passer ces deux valeurs comme deuxième et troisième arguments à mq_send.

+0

désolé, il a été mentionné en faux en question, il a été édité maintenant mq_send (m_qSendDesc, (char *) & inData, inSize, inPriority); – venkysmarty

+0

hi - vous ne pouvez pas simplement transformer une structure en char * pour le convertir - vous devez coder la conversion, puisque vous transformez aussi ints en char *. –

3

Le récepteur se bloque car il ne peut pas accéder à votre pointeur qui est uniquement disponible pour une utilisation depuis le programme expéditeur. Vous devez envoyer les données réelles à la file d'attente des messages, pas un pointeur.

+0

pouvez-vous s'il vous plaît dire comment pouvons-nous y parvenir avec des structures? – venkysmarty

+0

exactement comme Numenor dit - il suffit de faire les deux nombres non signés un en-tête de votre message, suivi par les données de caractères réels au lieu d'un pointeur. – kdo