OVH Cloud OVH Cloud

Socket Java et C++

22 réponses
Avatar
David Noyelle
Bonjour a tous,

j'ai 2 programmes :

- un programme en C++ qui fait office de socket d'ecoute.
- un programme Java qui se connecte a la socket du programme C++.

Jusqu'ici la connexion fonctionne bien. Une fois la connexion creee, le
programme Java demande au programme C++ de lui transmettre une structure qui
est la suivante:
--------------------------------------------
typedef struct
{
CONFIG_TRACE trace;
CONFIG_COM config_com;
WORD PORT_ECOUTE;
WORD PORT_ECOUTE_ADMIN;
WORD modbus_timeout;
WORD modbus_turnaround;
} CONFIG;
--------------------------------------------

Mais le programme Java ne recoit pas correctement cette structure (a
l'affichage ca me donne "_CONFIG") car la socket Java place le contenu de
son entree (in = socket.getInputStream()) dans une variable de type String
(inString = monProg.in.readLine()) .

Ma question est la suivante : est-ce que je dois creer une structure du cote
Java qui soit identique a la structure du cote C++ pour pouvoir la recuperer
correctement ? Ou est-ce que je peux recuperer cette structure dans un
tableau ?

Par exemple : structureJava = monProg.in.readLine()
tableauJava = monProg.in.readLine()

Je precise que la structure emise par le programme C++ est essentiellement
constituee de variable de type WORD (16 bits - short) et DWORD (32 bits -
int) .

Merci d'avance pour vos suggestions,

--
David NOYELLE
davidnoyelle chez yahoo point fr

10 réponses

1 2 3
Avatar
drkm
"David Noyelle" writes:

j'ai 2 programmes :

- un programme en C++ qui fait office de socket d'ecoute.
- un programme Java qui se connecte a la socket du programme C++.

Jusqu'ici la connexion fonctionne bien. Une fois la connexion creee, le
programme Java demande au programme C++ de lui transmettre une structure qui
est la suivante:


[...]

Je pense que la solution consiste à mettre en place un protocole de
transfert de ta structure. L'émetteur converti la structure en une
chaîne de caractères d'un format que tu définis. Le récepteur reçoit
cette chaîne et l'interprète selon le dit format. Pour les détails,
comme le problème BE/LE, je laisse d'autres contributeurs te
renseigner.

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Avatar
Emmanuel Feller
"David Noyelle" a écrit dans le message de
news:411ba18b$0$22040$
Bonjour a tous,

[...]

Ma question est la suivante : est-ce que je dois creer une structure du
cote

Java qui soit identique a la structure du cote C++ pour pouvoir la
recuperer

correctement ? Ou est-ce que je peux recuperer cette structure dans un
tableau ?
[....]


Petite règle de base : faire le plus possible des échanges en texte, pas en
données binaires.
Les avantages :
- pas de pb en cas de migration d'un env à l'autre de ta partie C++
- pas d'adhérence entre ton java et ton peer ici le C++.
L'incovénient c'est que tu dois écrire un parseur pour récupérer ton flux un
peu plus complexe.

Bon ca c'est beau mais ca répond pas à ta question. Je dirais que c'est
comme tu veux, mais ca semble plus raisonnable de créer une classe qui mappe
la structure.

Maintenant voyons du coup l'aspect protocole de communication.
Le plus simple est de définir un séparateur de champs et un séparateur de
message et d'écrire coté C++ tes champs en texte séparés par ton délimiteur.
Le début de message et la fin de message sont ton délimiteur de message.
Ainsi tu écris @@32767&#&32134&#&blabla@@ ... au lieu de FFFFFFCBblabla.

Du cote java, tu prend un stringtokenizer pour récuperer tes bouts et après
tu n'as plus qu'à peupler ta classe qui mappe la structure.

Tu évites les problèmes présents et à venir comme ça.
Si tes messages sont complexes, tu peux voir à échanger un flux XML pour
être flexible.
(Je suis raisonnable, je ne te conseille pas de faire tes échange sur http
... ;)) )
Emmanuel

Avatar
kanze
drkm wrote in message
news:...
"David Noyelle" writes:

j'ai 2 programmes :

- un programme en C++ qui fait office de socket d'ecoute.
- un programme Java qui se connecte a la socket du programme C++.

Jusqu'ici la connexion fonctionne bien. Une fois la connexion creee,
le programme Java demande au programme C++ de lui transmettre une
structure qui est la suivante:


[...]

Je pense que la solution consiste à mettre en place un protocole de
transfert de ta structure. L'émetteur converti la structure en une
chaîne de caractères d'un format que tu définis. Le récepteur reçoit
cette chaîne et l'interprète selon le dit format.


Tout à fait exact, sauf que je dirais « chaîne d'octets », plutôt que
chaîne de caractères. Dans la mésure du possible, il est préférable de
passer par un format texte, mais ce n'est pas absolument nécessaire. En
revanche, il faut bien définir le format des données dans le protocol
dans tous les cas.

Pour les détails, comme le problème BE/LE, je laisse d'autres
contributeurs te renseigner.


Vue qu'on transmet un flux d'octets, il n'y a pas de problème BE/LE.

Typiquement, en C++, on définit d'une part un streambuf basé sur des
sockets, de l'autre un nouveau type de flux qui dérive de ios (mais non
de istream ou de ostream) qui se sert des streambuf pour transmettre les
octets. L'idiome, c'est que le flux s'occupe du formattage, et le
streambuf et ses dérivés des entrées/sorties proprement dites.

En Java, c'est un peu moins propre, ou plutôt, il n'y a pas d'idiome
aussi consacré. Le java.net.Socket permet d'obtenir un
java.io.InputStream et un java.io.OutputStream, qui à leur tour s'occupe
de lire de l'écrire des octets (type byte en Java). Ce qui se passe par
la suite est en revanche moins clair.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
M. B.
a écrit dans le message de news:


Tout à fait exact, sauf que je dirais « chaîne d'octets », plutôt que
chaîne de caractères. Dans la mésure du possible, il est préférable de
passer par un format texte, mais ce n'est pas absolument nécessaire. En
revanche, il faut bien définir le format des données dans le protocol
dans tous les cas.



La remarque d'Emmanuel Feller me parait fort judicieuse : utiliser un
flux XML pour une grande flexibilite.

D'autant que ce flux peut alors servir pour une serialisation tout aussi
flexible.

MB

Avatar
Michaël Delva
Pour les détails, comme le problème BE/LE, je laisse d'autres
contributeurs te renseigner.



Qu'est-ce que c'est que ces problèmes de BE/LE? J'en ai déjà entendu
parler, mais je ne sais pas ce que c'est?


Avatar
Arnaud Debaene
Michaël Delva wrote:
Pour les détails, comme le problème BE/LE, je laisse d'autres
contributeurs te renseigner.



Qu'est-ce que c'est que ces problèmes de BE/LE? J'en ai déjà entendu
parler, mais je ne sais pas ce que c'est?


Big Endian / Littel Endian. Un nombre représenté sur plusieurs octets peut
l'être de 2 façons : soit avec l'octet de poids faible à l'adresse la plus
basse (little endian), soit avec l'octet de poids fort à l'adresse la plus
basse (big endian). Différents processeurs utilisent l'une ou l'autre de ces
conventions. Si des machines avec des processeurs différents communiquent
entre elles, il faut en tenir compte.

Généralement, on utilise la convention Internet (Big Endian si je me
souviens bien) pour sérialiser les données, et on utilise les fonctions
htons, htonl, ntohs et ntohl pour passer de la convention locale à la
machine à la convention Internet et vice-versa. Sur une machine big endian,
ces fonctions ne font rien mais sur un machine little endian, elles
inversent l'ordre des octets de leur paramètre.

Arnaud



Avatar
Michaël Delva
Avatar
Jean-Christophe Garnier

Bonjour a tous,

j'ai 2 programmes :

- un programme en C++ qui fait office de socket d'ecoute.
- un programme Java qui se connecte a la socket du programme C++.

Jusqu'ici la connexion fonctionne bien. Une fois la connexion creee, le
programme Java demande au programme C++ de lui transmettre une structure qui
est la suivante:
--------------------------------------------
typedef struct
{
CONFIG_TRACE trace;
CONFIG_COM config_com;
WORD PORT_ECOUTE;
WORD PORT_ECOUTE_ADMIN;
WORD modbus_timeout;
WORD modbus_turnaround;
} CONFIG;
--------------------------------------------

Mais le programme Java ne recoit pas correctement cette structure (a
l'affichage ca me donne "_CONFIG") car la socket Java place le contenu de
son entree (in = socket.getInputStream()) dans une variable de type String
(inString = monProg.in.readLine()) .

Ma question est la suivante : est-ce que je dois creer une structure du cote
Java qui soit identique a la structure du cote C++ pour pouvoir la recuperer
correctement ? Ou est-ce que je peux recuperer cette structure dans un
tableau ?

Par exemple : structureJava = monProg.in.readLine()
tableauJava = monProg.in.readLine()

Je precise que la structure emise par le programme C++ est essentiellement
constituee de variable de type WORD (16 bits - short) et DWORD (32 bits -
int) .

Merci d'avance pour vos suggestions,



Si j'étais toi, je ferais tout de suite du XML/RPC ou du SOAP... pas de

problème de type, portable sur d'autres langages et d'autres
plateformes, etc.
Cela vaut le coup de prendre le temps au début, on en gagne énormément
par la suite.
JC

Avatar
James Kanze
"M. B." writes:

|> a écrit dans le message de news:
|>

|> > Tout à fait exact, sauf que je dirais « chaîne d'octets », plutôt
|> > que chaîne de caractères. Dans la mésure du possible, il est
|> > préférable de passer par un format texte, mais ce n'est pas
|> > absolument nécessaire. En revanche, il faut bien définir le format
|> > des données dans le protocol dans tous les cas.

|> La remarque d'Emmanuel Feller me parait fort judicieuse : utiliser
|> un flux XML pour une grande flexibilite.

Ça dépend des buts récherchés. Si le but est d'utiliser un maximum de la
bande passante, l'XML est un bon moyen.

|> D'autant que ce flux peut alors servir pour une serialisation tout
|> aussi flexible.

Je ne comprends pas cette phrase.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
James Kanze
"Michaël Delva" writes:

|> >> Pour les détails, comme le problème BE/LE, je laisse d'autres
|> >> contributeurs te renseigner.

|> Qu'est-ce que c'est que ces problèmes de BE/LE? J'en ai déjà entendu
|> parler, mais je ne sais pas ce que c'est?

Ça signifie Big-Endian et Little-Endien, et ça fait référence à l'ordre
des octets dans un mot. Si on écrit un mot (int, etc.) phyiquement sur
un Sparc, et on le lit physiquement sur un PC, la valeur ne serait pas
la même.

Donc, on n'écrit que des octets, et il n'y a pas de problème.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
1 2 3