QNX – Illustration 03

petit_message.h

Le premier bloc décrit le fichier d'en-tête petit_message.h. Ce fichier doit être accessible à la fois au client et au serveur.

#ifndef PETIT_MESSAGE_H
#define PETIT_MESSAGE_H
#include <sys/iomsg.h>
#include <string>
struct petit_message {
   short type;
   sigevent event;
};
const int CODE_PULSATION = _PULSE_CODE_MINAVAIL+5,
          MSG_PULSATION_DESIREE = _IO_MAX+4;
const std::string NOM_SERVEUR =  "mon_premier_serveur";
#endif
client.cpp

Le deuxième bloc décrit le code du client.

Quelques liens pour en savoir plus sur des outils clés de cet exemple :

#include "petit_message.h"
#include <sys/neutrino.h>
#include <sys/iomsg.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <unistd.h>
#include <iostream>
#include <cstdlib>
#include <cerrno>
using namespace std;
int main() {
   int id_canal = ChannelCreate( 0 );
   int id_connexion = ConnectAttach( 0, 0, id_canal, _NTO_SIDE_CHANNEL, 0 );
   //
   // message a emettre au serveur
   //
   petit_message msg;
   SIGEV_PULSE_INIT(
      &msg.event, id_connexion, SIGEV_PULSE_PRIO_INHERIT, CODE_PULSATION, 0
   );
   msg.type = MSG_PULSATION_DESIREE;
   //
   // identifier le serveur
   //
   int id_connexion_serveur = name_open( NOM_SERVEUR.c_str(), 0 );
   if (id_connextion_serveur == -1) {
      cerr << "Client: serveur introuvable, code " << errno << '\n';
      exit(1);
   }
   //
   // s'abonner pour que le serveur nous rappelle (synchrone, sens strict)
   //
   MsgSend(id_connexion_serveur, &msg, sizeof msg, 0, 0);
   //
   // attente bloquante d'une pulsation
   //
   _pulse pulse;
   int rcvid = MsgReceivePulse(id_canal, &pulse, sizeof pulse, 0);
   cout << "Client: recu pulsation de valeur " << static_cast<int>(pulse.code)
        << ", souhaitait " << CODE_PULSATION << endl;
}
serveur.cpp

Le troisième bloc décrit le code du serveur.

Quelques liens pour en savoir plus sur des outils clés de cet exemple :

#include "petit_message.h"
#include <sys/neutrino.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <unistd.h>
#include <iostream>
#include <cstdlib>
#include <cerrno>
using namespace std;
int main() {
   //
   // s'attacher au nom que le client utilisera pour nous trouver. Le canal
   // correspondant a ce nom sera dans le name_attach_t* obtenu
   //
   name_attach_t *attach = name_attach(0, NOM_SERVEUR.c_str(), 0);
   if (!attach) {
      cerr << "Serveur: attacher a " << NOM_SERVEUR
           << ", code " << errno << '\n';
      exit(1);
   }
   //
   // mise en attente bloquante d'un message du client. Il est imperatif
   // de repondre (MsgReply()) dans un delai deterministe pour eviter de
   // bloquer le client inutilement
   //
   petit_message msg;
   int rcvid = MsgReceive(attach->chid, &msg, sizeof msg, 0);
   short msgType = msg.type;
   MsgReply(rcvid, 0, 0, 0);
   if (msgType == MSG_PULSATION_DESIREE) {
     //
     // simuler un traitement reel par une simple suspension
     //
     sleep(2);
     //
     // signaler un evenement au client (non bloquant)
     //
     MsgDeliverEvent(rcvid, &msg.event);
     cout << "Serveur: evenement livre au client" << endl;
  } else {
     cerr << "Serveur: message inattendu\n";
  }
}

Valid XHTML 1.0 Transitional

CSS Valide !