IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

[Socket] Récupération de structure C


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut [Socket] Récupération de structure C
    Voila j'ai un leger probleme.

    Je dois faire un ptit chat en socket multicast ..
    Seul probleme, il doit etre possible de faire un client en C qui va avec ..

    J'opte donc pour crée des paquet de taille fixe .. qui serait par exemple definie en C comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct PaquetChat
    {
    char Message[50];
    char Pseudo[20];
    short Type;
    short Color;
    }
    Mon probleme se situe en java ..
    J'arrive a crée le paquet pour l'envoie ... via des string buffer de taille fixe, etc ...

    Mais voila .. pour la recuperation, je recupere un tableau de byte.

    Voila mon probleme ..

    Dans mon exemple ma structure devrait faire
    72 byte ...

    J'ai donc un tableau de 72 byte.

    Comment puis-je "recuperer" mes differents champs ?

    Je pourrai refaire a chaque fois un Byte[] de la bonne taille que je remplirai via une boucle ...

    Et retransformerai ce tableau dans le format souhait mais c'est un peu lourd ...

    J'ai une autre solution, peut etre un peu mieux :

    Cree un ByteArrayInputStream sur le buffer de depart, cree un Byte[] de la taille de ce qu'on veut et faire un read(byte[] array) .. Et ensuite recreer un string sur ce byte[] ..


    Mais cela me semble fort lourd ...


    N'y a-t-il pas de meilleur moyen pour decomposer un tableau de byte en different champs plus rapidement ?
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Note : Me rappele plus des conventions C/C++ (faut dire qu'il y en a tant) mais je crois que meme la il est conseille d'avoir les membres d'une classe/struct qui commencent par des minuscules.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Mais cela me semble fort lourd ...
    Non c'est exactement ce qu'il faut faire lorsqu'on traite des protocoles de bas niveau. D'ou le fait que pas grand monde aime bidouiller comme ca.
    Par contre pour economiser de la memoire ou eviter de multiples allocations/deallocation, tu peux essayer dans la mesure du possible de reutiliser les tableaux/buffers d'expedition et de reception, plutot que de les reallouer a chaque fois.

    C => Java

    Attention lors de l'envoie cote C, si tu envoie la structure telle qu'elle sur la socket, suivant les platformes, les OS et les compilateurs, la structure peut avoir 1 ou plusieurs bits/octets supplementaires dits de padding. Sur certaines platformes c'est automatique des qu'une structure est composee de champs plus petits qu'un mot (short, char, ...). Cela est fait de maniere a avoir une taille ronde/entiere en memoire (un nombre entier de mots/words memoire), ce qui facilite la gestion de la memoire.
    D'ou le fait qu'un sizeof peut parfois retourner une taille plus grande que celle qu'on attend. Mieux vaut donc manuellement creer un tableau d'octets qu'on remplira soit-meme.

    A la reception cote Java si tu sais quelle taille fait chaque champs dans le tableau. Ce qui peut etre facilement fait avec des System.arraycopy() ou des boucles.

    lire 50x1 octets => message (char C = 1 octet*)
    lire 20x1 octets => nickname (char C = 1 octet*)
    lire 1x2 octets => type**
    lire 1x2 octets => color**

    *Un char Java fait 2 octets. D'ailleurs il te faudra probablement recopier ces 50 octets dans un tableau de 50 char, plutot qu'utiliser le constructeur de String qui prend un parametre un tableau d'octets.

    Java => C

    De la meme maniere, puisqu'un char Java fait 2 octets, fait bien attention quand tu convertit tes chaines Java en byte[]. Plutot que d'utiliser les methodes de la classe String, tu voudras peut-etre plutot utiliser qq chose dans le genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (int i = 0 ; i < s.length () ; i++) {
      byte b = (byte)s.charAt(i);
      ...
    }
    Evidement le gros pb est que tu perds/change/coupe tous les char > 255, donc tu perd le support de l'unidode. Si ton prog doit rester en ASCII, ou Latin1, c'est ok cependant.

    Sinon tu peux essayer un encodage style UTF-8 mais n'oublie pas que ca rallongera le tableau de byte (tous les caracters > 255 seront encodes en plusieurs chars) et il faut aussi que ton client C puisse supporter ce type d'encodage.

    General
    ** L'autre gros pb... c'est l'ordonnancement big-endian vs. little-endian pour tous les types numeriques dont la taille depasse 1 octet. Fait bien attention a l'ordre des bytes composant des shorts.

    Java est big-endian, il y a des fortes chances que ton prog C soit little-endian (s'il est compile/tourne sous Linux x32/x64 ou Win 32/64). Donc a un bout de la chaine (probablement du cote du client C puisque lui peut detecter s'il fonctionne en big ou little endian (voir manuel et macros de ton compilateur)) il faudra intervertir les octets des shorts a la reception ET a l'emmision.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre confirmé Avatar de keil
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    261
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 261
    Par défaut
    Merci Bouye pour ton reply, j'en apprend tous les jours avec toi !
    Autre chose à savoir, les compilo C et C++ peuvent avoir des normes assez différentes les une des autre, donc il te faudra déterminé les nombres d'octet que tes char, short et int occupent.
    sizeof(<type>)

    Du coté Java, si j'étais toi, je créerais une méthode qui recomposerai le flux en une structure (=classe) telle que celle que tu as en C.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 30
    Par défaut
    Sinon tu peut utiliser une interface corba, c'est plus lourd mais apriori "universel"...

  5. #5
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Le probleme est que je travail en upd ( en fait c un mini chat en multicast ), dont pas de flux mais un buffer ( byte[] ).

    Mais merci de votre aide.

    J'ai fait une tite classe ByteParser avec des fonctions static pour recuperer un String, un int ou un short à partir de son offset dans le tableau..

    Ca fonctionne, mais d'apres vos messages, je risque d'avoir deux probleme :
    • Le probleme de Big/Little endian
      Le probleme de la taille de la structure en C du au padding



    Donc a mon avis je vais modifier ma structure par une chaine du type
    monchamp1;monchamp2;monchamp2;<FINDELIGNE>

    Merci de votre aide
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     il te faudra déterminé les nombres d'octet que tes char, short et int occupent.  
    sizeof(<type>)
    Exact j'avais aussi oublie de point de detail-la... j'ai passe trop de temps avec GCC et Visual Studio sur Windows et Linux 32-bits moi.

    Si mes souvenirs sont pas trop foireux les regles de base des normes C/C++ sont :

    sizeof bool == non-specifiee depend de l'implementation
    sizeof char <= sizeof short <= sizeof int <= size long
    sizeof float <= sizeof double <= sizeof long double
    En general:
    sizeof char == 1
    sizeof float == 4 suivant la norme IEEE qui definit les nombres flottants.
    Sans plus de precision pour les autres meme si la plupart du temps (sur 32-bits) on attend :
    sizeof short == 2
    sizeof int == 4
    sizeof double == 8.
    Note: dans Visual Studio sizeof int == sizeof long == 4 et sizeof bool == 1

    Sans parler des types qui n'existent que sur certains compilateurs et pas d'autres (byte, long long, wchar, int64, ...).

    Il te faudra donc etre extra-prudent pour etre sur que le tableau d'octets aura toutjours la bonne taille en C et qu'ils soient toujours lus/cree correctement quels que soit la vrai taille des char et des short utilises par ton compilateur.

    En fait bien que la declaration d'une classe en Java soit plus compliquee (a ecrire) qu'une simple structure en C, l'implementation du code cote Java sera bien plus simple puisqu'on se tape de toutes ces considerations sur les tailles des types et les capacites des platformes et des compilateurs.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. C++ Socket envoi de structures sérialisées
    Par nfast dans le forum C++
    Réponses: 5
    Dernier message: 30/12/2012, 11h46
  2. [socket] Récupération d'images à intervalle régulier
    Par minod dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 09/05/2011, 14h24
  3. Parcours de fichier .avi et récupération de structures particulières
    Par Gandalf2008 dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 16/09/2010, 16h38
  4. [C#] Sockets, récupération de l'adresse IP locale
    Par dockurt2k dans le forum Windows Forms
    Réponses: 2
    Dernier message: 29/09/2006, 22h30
  5. [SOCKET] Envoi de structure
    Par Lolita59 dans le forum Réseau
    Réponses: 3
    Dernier message: 17/05/2006, 15h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo