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

conversion little endian big endian et viceversa [C/reseau] - C++ - Programmation

Marsh Posté le 19-03-2003 à 13:12:20    

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
Reply

Marsh Posté le 19-03-2003 à 13:12:20   

Reply

Marsh Posté le 19-03-2003 à 13:18:55    

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é...

Reply

Marsh Posté le 19-03-2003 à 13:19:42    

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
 

Reply

Marsh Posté le 19-03-2003 à 13:19:48    

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

Reply

Marsh Posté le 19-03-2003 à 13:21:50    

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
Reply

Marsh Posté le 19-03-2003 à 13:23:41    

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:

Reply

Marsh Posté le 19-03-2003 à 13:27:46    

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

Reply

Marsh Posté le 19-03-2003 à 14:27:45    

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.

Reply

Marsh Posté le 19-03-2003 à 20:09:53    

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

Reply

Marsh Posté le 19-03-2003 à 20:22:53    

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

Reply

Marsh Posté le 19-03-2003 à 20:22:53   

Reply

Marsh Posté le 19-03-2003 à 20:23:51    

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

Reply

Marsh Posté le 20-03-2003 à 07:11:17    

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
Reply

Marsh Posté le 21-03-2003 à 14:11:09    

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
Reply

Marsh Posté le 21-03-2003 à 14:16:54    

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

Reply

Marsh Posté le 21-03-2003 à 14:19:35    

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:

Reply

Marsh Posté le 21-03-2003 à 15:44:14    

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
Reply

Marsh Posté le 21-03-2003 à 16:21:05    

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
Reply

Marsh Posté le 22-03-2003 à 23:47:01    

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

Reply

Marsh Posté le 22-03-2003 à 23:54:25    

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)

Reply

Marsh Posté le 23-03-2003 à 01:17:18    

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
Reply

Marsh Posté le 24-03-2003 à 09:40:37    

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
Reply

Marsh Posté le 15-09-2003 à 20:48:31    

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 ..

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed