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
|
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;
}
|
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";
}
}
|