Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2379 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C/reseau] conversion little endian big endian et viceversa

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C/reseau] conversion little endian big endian et viceversa

n°337181
cooltwan
Posté le 19-03-2003 à 13:12:20  profilanswer
 

Quelqu'un a les routine pour faire ça
car je transmet via des sockets udp un message qui contient des float, des int et des doubles avec un client little endian et un serveur en big endian qui doit faire des operations style addition sur le message reçu et les renvoyer au client ?
 
"
Le client et le serveur vont échanger un message ayant la structure suivante :  
 
 
  +---------------+
  | integer |
  +---------------+
  | chaine 8 car. |
  |  |
  +---------------+
  | integer |
  +---------------+
  | float   |
  +---------------+
  | double   |
  |  |
  +---------------+
 
Le client initialise la structure, l'envoie au serveur. Le serveur imprime ce qu'il a reçu, modifie le contenu, et le renvoie au client qui imprime ce qu'il reçoit en retour.
"


Message édité par cooltwan le 19-03-2003 à 13:27:23
mood
Publicité
Posté le 19-03-2003 à 13:12:20  profilanswer
 

n°337184
djok_fb
C'était mieux avant!
Posté le 19-03-2003 à 13:18:55  profilanswer
 

dans la norme ISO, c'est la couche présentation qui fait ca...
mais la, tu pars quasi from scratch donc tu dois le faire toi-meme...désolé...

n°337185
SoWhatIn22
Posté le 19-03-2003 à 13:19:42  profilanswer
 

cooltwan a écrit :

Quelqu'un a les routine pour faire ça
car je transmet via des sockets udp un message qui contient des float, des int et des doubles avec un client little endian et un serveur en big endian qui doit faire des operations style addition sur le message reçu et les renvoyer au client ?


 
pour les entiers sur 32 bits
man htonl
man ntohl
 
pour les entiers sur 16 bits
man htons
man ntohs
 

n°337186
cooltwan
Posté le 19-03-2003 à 13:19:48  profilanswer
 

pour les int c'est facile (d'ailleurs avec htonl etc c'est deja fait) mais pour les float je vais pleurer  :sweat:

n°337187
gatorette
Posté le 19-03-2003 à 13:21:50  profilanswer
 

Pour faire ça, tu as les fonctions ntohl et htonl pour les u_longs et ntohs et htons pour les u_shorts.


---------------
each day I don't die is cheating
n°337189
cooltwan
Posté le 19-03-2003 à 13:23:41  profilanswer
 

gatorette a écrit :

Pour faire ça, tu as les fonctions ntohl et htonl pour les u_longs et ntohs et htons pour les u_shorts.


 
et pour les floats je fais comment ?  :pt1cable:

n°337191
Clie
Posté le 19-03-2003 à 13:27:46  profilanswer
 

Pour les float c'est pareil
C'est la donnee qui est inverse
T'echange les octets

n°337246
nraynaud
lol
Posté le 19-03-2003 à 14:27:45  profilanswer
 

cooltwan a écrit :

Quelqu'un a les routine pour faire ça
car je transmet via des sockets udp un message qui contient des float, des int et des doubles avec un client little endian et un serveur en big endian qui doit faire des operations style addition sur le message reçu et les renvoyer au client ?
 
"
Le client et le serveur vont échanger un message ayant la structure suivante :  
 
 
  +---------------+
  | integer |
  +---------------+
  | chaine 8 car. |
  |  |
  +---------------+
  | integer |
  +---------------+
  | float   |
  +---------------+
  | double   |
  |  |
  +---------------+
 
Le client initialise la structure, l'envoie au serveur. Le serveur imprime ce qu'il a reçu, modifie le contenu, et le renvoie au client qui imprime ce qu'il reçoit en retour.
"


 
Il existe existe une bibliothèque pour ça : XDR (genre external data representation), C'est une norme internationale.
 
Le binding C est une merde sans nom (qui finalement s'itègre bien dans le langage).
 
C'est la partie présentation des RPC.

n°337708
cooltwan
Posté le 19-03-2003 à 20:09:53  profilanswer
 

de toute façon le prof veut qu'on fasse les routines nous memes donc on va faire mumuse pour remettre les octets dans le bon ordre sans compter que le client est sur une becane 64 bit et le serv sur une plateforme 32 bits

n°337735
youdontcar​e
Posté le 19-03-2003 à 20:22:53  profilanswer
 

il reste la façon simple : tout passer en texte :D

mood
Publicité
Posté le 19-03-2003 à 20:22:53  profilanswer
 

n°337736
cooltwan
Posté le 19-03-2003 à 20:23:51  profilanswer
 

le serveur doit modifier avec des operations style +1 les champs du message donc pas possible  :pt1cable:

n°338150
Musaran
Cerveaulté
Posté le 20-03-2003 à 07:11:17  profilanswer
 

Code :
  1. #include <limits.h>
  2. typedef int T;
  3. //Inverse l'ordre des octets
  4. T ByteReverse(const T in){
  5. T out ;
  6. const char* pin = (const char*) &in       ;
  7.       char* pout= (      char*)(&out+1)-1 ;
  8. int i;
  9. for(i= sizeof(T) ; i>0 ; --i){
  10.  *pout-- = *pin++ ;
  11. }
  12. return out ;
  13. }
  14. //Inverse l'ordre des bits
  15. T BitReverse(T in){
  16. const int nbits= sizeof(T)*CHAR_BIT ;
  17. T out= 0 ;
  18. int n;
  19. for( n= 0 ; ; ){//forever   
  20.  out|= in&0x01 ; //copie du bit de poids faible   
  21.  n++ ;           //compter les bits copiés   
  22.  if(n==nbits)    //si tous les bits sont traités...
  23.   break ;       //...arrêter
  24.  in >>= 1 ;      //vider vers la droite (préparer le suivant)...   
  25.  out<<= 1 ;      //...pour remplir vers la gauche (préparer la place)   
  26. }
  27.    return out ;
  28. }


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°339625
cooltwan
Posté le 21-03-2003 à 14:11:09  profilanswer
 

c bizarre quand  je fais printf de sizeof d'un entier sur le serveur 64 bits j'ai que 4 octets soit 32 bits ???  :sarcastic:
 
(serveur dec qlpha)
#include <stdio.h>
 
main()
{
int i=2;
printf("taille d'un entier %d",sizeof(i));
}
 
1010 amagnier vega:~> cc -o taille taille.c
1011 amagnier vega:~> taille
taille d'un entier 4
1012 amagnier vega:~>


Message édité par cooltwan le 21-03-2003 à 14:14:26
n°339630
e_esprit
Posté le 21-03-2003 à 14:16:54  profilanswer
 

parce que par defaut c'est pas un long qui est utilisé.

n°339632
cooltwan
Posté le 21-03-2003 à 14:19:35  profilanswer
 

ok j'ai trouve merci  :jap:  
 
"
Note :  Remarquez que, d'après ce qui précède, le type int devrait être codé sur 64 bits sur les machines 64 bits. Le type long int devant lui être supérieur, il doit également être codé sur 64 bits ou plus. Le type short int peut alors être sur 16 ou sur 32 bits. Il n'existe donc pas, selon la norme, de type permettant de manipuler les valeurs 16 bits sur les machines 64 bits si le type short int est codé sur 32 bits, ou, inversement, de type permettant de manipuler les valeurs 32 bits si le type short int est codé sur 16 bits.
 
Afin de résoudre ces problèmes, la plupart des compilateurs brisent la règle selon laquelle le type int est le type des entiers natifs du processeur, et fixent sa taille à 32 bits quelle que soit l'architecture utilisée. Ainsi, le type short est toujours codé sur 16 bits, le type int sur 32 bits et le type long sur 32 ou 64 bits selon que l'architecture de la machine est 32 ou 64 bits. Autrement dit, le type qui représente les entiers nativement n'est plus le type int, mais le type long. Cela ne change pas les programmes 32 bits, puisque ces deux types sont identiques dans ce cas. Les programmes destinés aux machines 64 bits pourront quant à eux être optimisés en utilisant le type long à chaque fois que l'on voudra utiliser le type de données natif de la machine cible. Les programmes 16 bits en revanchent ne sont en revanche plus compatibles avec ces règles, mais la plupart des compilateurs actuels ne permettent plus de compiler des programmes 16 bits de toutes manières.  
"
 
a mon avis y a une coquille dans le sujet et le deuxieme champ du message doit surement etreun long  :wahoo:

n°339689
cooltwan
Posté le 21-03-2003 à 15:44:14  profilanswer
 

niveau code je fais faire bourrain avec un truc style:

Code :
  1. short convert_short(short in)
  2. {
  3.   short out;
  4.   char *p_in = (char *) ∈
  5.   char *p_out = (char *) &out;
  6.   p_out[0] = p_in[1];
  7.   p_out[1] = p_in[0];
  8.   return out;
  9. }
  10. long convert_long(long in)
  11. {
  12.   long out;
  13.   char *p_in = (char *) ∈
  14.   char *p_out = (char *) &out;
  15.   p_out[0] = p_in[3];
  16.   p_out[1] = p_in[2];
  17.   p_out[2] = p_in[1];
  18.   p_out[3] = p_in[0];
  19.   return out;
  20. }


Message édité par cooltwan le 21-03-2003 à 15:44:33
n°339726
gatorette
Posté le 21-03-2003 à 16:21:05  profilanswer
 

Ca ne marchera pas ! En effet, il faut intervertir les bits et pas les octets !
La bonne solution a été apportée par Musaran ici.


---------------
each day I don't die is cheating
n°340591
cooltwan
Posté le 22-03-2003 à 23:47:01  profilanswer
 

pourtant ça marche l'inversion des octets chez moi je viens de tester tout ça

n°340595
mrbebert
Posté le 22-03-2003 à 23:54:25  profilanswer
 

gatorette a écrit :

Ca ne marchera pas ! En effet, il faut intervertir les bits et pas les octets !
La bonne solution a été apportée par Musaran ici.

:heink:  
La conversion little endian/big endian, ca concerne les octets, pas les bits
(au moins sur les entiers)

n°340629
LeGreg
Posté le 23-03-2003 à 01:17:18  profilanswer
 

mrBebert a écrit :

:heink:  
La conversion little endian/big endian, ca concerne les octets, pas les bits
(au moins sur les entiers)


 
de toute façon les bits ne sont pas adressables
donc on se fiche dans quel ordre ils sont envoyés
(sauf si tu fais vraiment du bas niveau...)
 
LeGreg


---------------
voxel terrain render engine | animation mentor
n°341077
gatorette
Posté le 24-03-2003 à 09:40:37  profilanswer
 

mrBebert a écrit :

:heink:  
La conversion little endian/big endian, ca concerne les octets, pas les bits
(au moins sur les entiers)


 
Oui... je me suis rendu compte de ma connerie vendredi soir  :sweat: et évidemment pas d'accès internet du week-end.
 
Note to myself: Toujours tourner dix fois les doigts dans sa bouche avant de répondre...
 
Pour me rattraper (si c'est encore possible), voila deux codes de conversion un peu particuliers (ça marche chez moi, mais je ne recommande pas leur utilisation) :

Code :
  1. u_short my_htons( u_short inp )
  2. {
  3. u_char *input = (u_char *)&inp;
  4. input[0]^=input[1]^=input[0]^=input[1];
  5. return inp;
  6. }
  7. u_long my_htonl( u_long inp )
  8. {
  9. u_char *input = (u_char *)&inp;
  10. input[0]^=input[3]^=input[0]^=input[3];
  11. input[1]^=input[2]^=input[1]^=input[2];
  12. return inp;
  13. }


 
Si vous voulez plus d'infos sur le "stupid xor trick", allez voir ici.


Message édité par gatorette le 24-03-2003 à 10:05:09

---------------
each day I don't die is cheating
n°515250
stancw
Parle à Monkey ...
Posté le 15-09-2003 à 20:48:31  profilanswer
 

J'AI UN PROBLEME AVEC UN FLOTANT :
 
Dans un fichier binaire écris sous sun : 00 00 40 40 ça donne quoi comme flottant sous Windows d'aprés vous ???
 
merci de m'aider ..

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C/reseau] conversion little endian big endian et viceversa

 

Sujets relatifs
répertoire, racourci réseau et ouverture de fichiers...Conversion hexa en char*
Désactiver et réactiver une carte réseauProblème de conversion de float en int
conversion hexa -> Decimal[Delphi] p'tit problème conversion cpp vers delphi
[Résolu][Php] Problème explorateur de fichiers (lecteur réseau)Communication avec un serveur DNS : conversion byte en hexa
[MySQL] Little Question sur fonction RIGHT[Delphi] p'tit blem de conversion
Plus de sujets relatifs à : [C/reseau] conversion little endian big endian et viceversa


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR