affichage bit par bit

affichage bit par bit - C - Programmation

Marsh Posté le 09-07-2010 à 18:24:39    

bonjour
est il possible d'afficher chaque bit (0 ou 1) sous forme d'entier, d'un entier ?
 
Par exemple, si j'ai un entier qui vaut 2 dans mon code, ça fait en binaire qque chose comme 000000 ... 10 (sur 32 bit j'imagine)
 
est ce que je peux afficher ça à l'écran ? (cad 0 0 ... 0 1 0)  
 
merci par avance

Reply

Marsh Posté le 09-07-2010 à 18:24:39   

Reply

Marsh Posté le 09-07-2010 à 18:29:51    

oui, tu peux.
mask, shift, quel est ton problème ?


---------------
last.fm
Reply

Marsh Posté le 09-07-2010 à 20:03:29    

Code :
  1. int var=<la valeur>
  2. int i;
  3. for (i=0; i < sizeof(var) * 8; i++)
  4.    printf("%d" % var & (0x01 << (sizeof(var) * 8 - i - 1)));


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 11-07-2010 à 23:51:08    

Sve@r a écrit :

Code :
  1. int var=<la valeur>
  2. int i;
  3. for (i=0; i < sizeof(var) * 8; i++)
  4.    printf("%d" % var & (0x01 << (sizeof(var) * 8 - i - 1)));


 


salut,
merci pour vos réponses, c'est juste une question qui me passait par la tête car je n'ai pas l'habitude d'utiliser les opérateurs de bit.

 

Quand on parle de "trois binaire" par exemple, ça veut juste dire que c'est un trois sous forme d' "int" non ?

 

Sve@r, est ce que tu peux expliciter ce que veux dire "0x01" ? Pourquoi est ce que 1 doit être écrit en hexa ?

 

Si j'ai bien compris, tu fais un masquage en décalant le 1, soit par exemple pour 9 = 00000000 ... 1001 (sur 32 bits) :

 

0000000000 ... 1001 & 0000000 ...... 00001
0000000000 ... 1001 & 0000000 ...... 00010
0000000000 ... 1001 & 0000000 ...... 00100
.
.
.
0000000000 ... 1001 & 1000000 ...... 00000

 


c'est ça ?

 

merci par avance

Message cité 1 fois
Message édité par in_your_phion le 11-07-2010 à 23:53:21
Reply

Marsh Posté le 12-07-2010 à 08:54:12    

in_your_phion a écrit :

Quand on parle de "trois binaire" par exemple, ça veut juste dire que c'est un trois sous forme d' "int" non ?


3 en binaire c'est 11
 

in_your_phion a écrit :

Sve@r, est ce que tu peux expliciter ce que veux dire "0x01" ? Pourquoi est ce que 1 doit être écrit en hexa ?


Rien n'est obligatoire en matière d'écriture. C'est juste une convention. Quand on utilise des flags booléens, on peut les écrire
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
ou bien
0x001, 0x002, 0x004, 0x008, 0x010, 0x020, 0x040, 0x080, 0x100, ...
Avec la seconde écriture, on perçoit (à mon sens) mieux la logique de la série. De plus, la conversion hexa->binaire se fait de tête (chaque digit du chiffre hexa est écrit en binaire sur 4 digits) alors que la conversion décimal->binaire nécessite un calcul (division puis récupération des restes)
 

in_your_phion a écrit :

Si j'ai bien compris, tu fais un masquage en décalant le 1, soit par exemple pour 9 = 00000000 ... 1001 (sur 32 bits) :
 
0000000000 ... 1001 & 0000000 ...... 00001
0000000000 ... 1001 & 0000000 ...... 00010
0000000000 ... 1001 & 0000000 ...... 00100
.
.
.
0000000000 ... 1001 & 1000000 ...... 00000
 
 
c'est ça ?


Exact

Message cité 1 fois
Message édité par Sve@r le 12-07-2010 à 08:57:44

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 12-07-2010 à 22:28:30    

merci!

 
Sve@r a écrit :


3 en binaire c'est 11

 

en fait, je pensais à un message qu'on code ou qu'on décode pour envoyer à un autre programme. Souvent, on voit le message avec des balises du style "3 binaire à la fin" (ce qui correspond à STX/ETX en ASCII je crois). Dans ce cas, ça veut dire qu'on code/décode tout le message en ASCII en regardant si à la fin il y a la balise ETX ?

 

par exemple, pour un message du type <STX>xxxxxxxx<ETX> (ou xxx c'est les données) je décode en ASCII ?

 


Message édité par in_your_phion le 13-07-2010 à 09:53:57
Reply

Marsh Posté le 13-07-2010 à 12:30:04    

l'ascii, c'est une table de caractère. Ce n'est donc qu'un autre choix de représentation de tes valeurs. Si tu dois lire un octet qui a la valeur 3, que ce soit du binaire, que ce soit de l'hexa, que ce soit du décimal, que ce soit le caractère ascii 3, ca revient au même. Par contre, évidemment, le 3ème caractère de la table ascii n'est pas le caractère '3'.
 
Bref, dans ton cas, si c'est un délimiteur pour t'annoncer des débuts ou fins de blocs sémantiques dans tes données binaires, j'ai envie de te dire de ne pas te soucier de questions d'ascii, considère que c'est un 3.


---------------
last.fm
Reply

Marsh Posté le 18-07-2010 à 11:26:31    

theshockwave a écrit :

l'ascii, c'est une table de caractère. Ce n'est donc qu'un autre choix de représentation de tes valeurs. Si tu dois lire un octet qui a la valeur 3, que ce soit du binaire, que ce soit de l'hexa, que ce soit du décimal, que ce soit le caractère ascii 3, ca revient au même. Par contre, évidemment, le 3ème caractère de la table ascii n'est pas le caractère '3'.

 

Bref, dans ton cas, si c'est un délimiteur pour t'annoncer des débuts ou fins de blocs sémantiques dans tes données binaires, j'ai envie de te dire de ne pas te soucier de questions d'ascii, considère que c'est un 3.

 

hello
ok, merci pour tes explications! J'aurais encore une autre question si possible  :o C'est un peu du C++ car c'est avec une classe à l'origine, mais bon ce serait exactement pareil avec une structure en C donc je vais expliquer avec ça : si j'ai une structure avec des champs / valeurs, par exemple :

 
Code :
  1. typedef struct MaStructure {
  2.      int id;
  3.      double price;
  4.      char clientName[32];
  5.      char optional[23];
  6. } MaStructure;
 


Dans mon programme, je créer des objets avec cette structure :

 
Code :
  1. MaStructure ms;
  2. ms.id = 123456;
  3. ms.price = 12.00;
  4. strcpy(ms.clientName,"blablabla" );
  5. strcpy(ms.optional,"" );
 

ou encore je créer d'autres objets avec plus ou moins de champs, ils devront êtres encodés avant d'être envoyés, non ?

 

Comment je peux encoder cette structure ? Il faudrait que je fasse une boucle sur les champs de la structure ? c'est possible ?

 

En fait, je crois que c'est lié à la serialization en binaire, mais je sais pas trop comment faire, c'est compliqué ?

Message cité 1 fois
Message édité par in_your_phion le 18-07-2010 à 11:45:21
Reply

Marsh Posté le 18-07-2010 à 17:57:18    

in_your_phion a écrit :

si j'ai une structure avec des champs / valeurs, par exemple :
 

Code :
  1. typedef struct MaStructure {
  2.      int id;
  3.      double price;
  4.      char clientName[32];
  5.      char optional[23];
  6. } MaStructure;


 
 
Dans mon programme, je créer des objets avec cette structure :
 

Code :
  1. MaStructure ms;
  2. ms.id = 123456;
  3. ms.price = 12.00;
  4. strcpy(ms.clientName,"blablabla" );
  5. strcpy(ms.optional,"" );


 
ou encore je créer d'autres objets avec plus ou moins de champs, ils devront êtres encodés avant d'être envoyés, non ?


A toi de voir. Rien ne t'oblige à remplir les champs. Dans le cas où tu t'abstiens, ils auront quand-même une valeur définie par l'état de la mémoire à ce moment là...
 

in_your_phion a écrit :

Comment je peux encoder cette structure ? Il faudrait que je fasse une boucle sur les champs de la structure ? c'est possible ?


Non. On peut pas boucler sur les champs. Surtout que l'optimiseur peut rajouter des bits intermédiaires pour caler la taille de la structure sur une puissance de 2 (plus rapide si on gère par la suite des tableaux de structures)
 
Mais rien ne t'empêche d'utiliser la notation "initialisation"

Code :
  1. MaStructure tab[]={
  2.     {123456, 12.0, "blablabla", ""},
  3.     {789012, 13.0, "blablabla", ""},
  4.     {345678, 13.0, "blablabla", ""},
  5.     {901234, 14.0, "blablabla", ""},
  6.     {567890, 15.0, "blablabla", ""},
  7.     {-1, 0.0, "", ""},            // Permet en plus de savoir où s'arrêter
  8. };
  9. MaStructure *pt;
  10. for (pt=tab, pt->id != -1; pt++)
  11.     printf("id: %d, price: %f, name: %s\n", pt->id, pt->price, pt->name);


Message édité par Sve@r le 18-07-2010 à 17:57:38

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 18-07-2010 à 23:03:30    

hello,
ok merci! je vais essayer ta méthode je pense, mais j'ai un formalisme objet alors ce sera peut être un peu plus compliqué

 

Juste pour être sûr, quand j'écris dans le buffer de sortie (qui va être envoyé à l'autre application - cliente ou serveur), ce serait comme ça ?

 
Code :
  1. unsigned char sendBuffer[512]; //mon buffer de sortie
  2. int sizeTotal=12;
  3. int stx = 3; // STX
  4. const char * info = "userId01";
  5. const char *paddingSpace = "  ";
  6. unsigned char * pbuf = sendBuffer;
  7. memcpy(pbuf, &size , sizeof(sizeTotal));
  8. pbuf+=4; //un int = 4 octets
  9. memcpy(pbuf, info, sizeof(char) * 12);
  10. pbuf+=12;
  11. memcpy(pbuf, paddingSpace, sizeof(char) * 2 );
  12. pbuf+=2;
  13. memcpy(pbuf, &stx, sizeof(int) );


Message cité 1 fois
Message édité par in_your_phion le 18-07-2010 à 23:06:42
Reply

Marsh Posté le 18-07-2010 à 23:03:30   

Reply

Marsh Posté le 21-07-2010 à 22:41:50    

in_your_phion a écrit :

hello,
ok merci! je vais essayer ta méthode je pense, mais j'ai un formalisme objet alors ce sera peut être un peu plus compliqué  
 
Juste pour être sûr, quand j'écris dans le buffer de sortie (qui va être envoyé à l'autre application - cliente ou serveur), ce serait comme ça ?
 

Code :
  1. unsigned char sendBuffer[512]; //mon buffer de sortie
  2. int sizeTotal=12;
  3. int stx = 3; // STX
  4. const char * info = "userId01";
  5. const char *paddingSpace = "  ";
  6. unsigned char * pbuf = sendBuffer;
  7. memcpy(pbuf, &size , sizeof(sizeTotal));
  8. pbuf+=4; //un int = 4 octets
  9. memcpy(pbuf, info, sizeof(char) * 12);
  10. pbuf+=12;
  11. memcpy(pbuf, paddingSpace, sizeof(char) * 2 );
  12. pbuf+=2;
  13. memcpy(pbuf, &stx, sizeof(int) );




 
Au lieu de faire pbuf+=4, fais donc pbuf+=sizeof(le truc précédent qui y a été stocké). Ce sera un poil plus portable.  
Sinon en ce qui concerne ta "sérialisation", la méthode est correcte. Mais tu ne pourras récupérer ton objet de l'autre coté que si tu te trouves sur la même architecture, avec le même compilo, le même processeur, etc. Parce que chaque architecture a sa propre façon de gérer les nombres et les structures. Dommage que Emmanuel ne soit pas là, il a déjà écrit des trucs à ce sujet...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 21-07-2010 à 23:22:43    

salut,
merci pour ta réponse! :)

 

donc par exemple il faudrait faire :

Code :
  1. memcpy(pbuf, &sizeTotal , sizeof(int));
  2. pbuf+=sizeof*sizeTotal;
 

?

 
Sve@r a écrit :


chaque architecture a sa propre façon de gérer les nombres et les structures.

 

ça a un rapport avec le codage little endian/big endian ? et si j'envoie juste ce buffer de char, ça sera toujours un buffer de char de l'autre côté non ? (Avec un décodage pê différent mais ce ne sera pas à moi de le gérer)

 


Message cité 2 fois
Message édité par in_your_phion le 21-07-2010 à 23:24:47
Reply

Marsh Posté le 22-07-2010 à 14:18:48    

in_your_phion a écrit :


ça a un rapport avec le codage little endian/big endian ? et si j'envoie juste ce buffer de char, ça sera toujours un buffer de char de l'autre côté non ? (Avec un décodage pê différent mais ce ne sera pas à moi de le gérer)


 
par convention, l'endianness sur les réseaux est en big endian. Si tu fais ta petite tambouille dans ton coin et que ton appli tourne sur deux machines à toi qui fonctionnent sur la même architecture, ca ne te posera pas de souci de ne pas respecter cette convention. Par contre, si tu dois communiquer avec de vrais clients, ca risque des les agacer de recevoir des données qui sont juste des tableaux de caractères qui représentent des entier dans ton endianness à toi.
 
Qui plus est, effectivement, le padding de tes structures est à prendre en compte. Je ne peux qu'appuyer le conseil qu'on t'a fait précédemment, à savoir : utiliser sizeof.


---------------
last.fm
Reply

Marsh Posté le 22-07-2010 à 18:53:27    

in_your_phion a écrit :

salut,
merci pour ta réponse! :)
 
donc par exemple il faudrait faire :

Code :
  1. memcpy(pbuf, &sizeTotal , sizeof(int));
  2. pbuf+=sizeof*sizeTotal;


 
?


Code :
  1. memcpy(pbuf, &sizeTotal , sizeof(sizeTotal));
  2. pbuf+=sizeof(sizeTotal);


 

in_your_phion a écrit :

et si j'envoie juste ce buffer de char, ça sera toujours un buffer de char de l'autre côté non ?


Oui mais non. Si tu descends tes nombres en octets, ils seront écrits dans l'ordre que ta machine utilise. Si de l'autre coté la machine les code dans l'autre sens...
Exemple: le nombre 500 est codé 1F04 en binaire (ici hexa mais c'est pareil). Tu envoies donc 1F puis 04. De l'autre coté, il reçoit 1F puis 04 comme il faut. Manque de bol, lui il code dans l'autre sens. Donc chez-lui, ce 1F04 sera décodé en 95.
 

in_your_phion a écrit :

(Avec un décodage pê différent mais ce ne sera pas à moi de le gérer)


Ouais t'as raison. T'as qu'à benner tes octets en vrac et le bonobo d'en face n'aura qu'à se dém... pour remettre tout ça dans l'ordre. Tant qu'à faire, tu conclues ton envoie par "ce puzzle 5000 pièces vous a été offert par [:jean-guitou]"
 
 

in_your_phion a écrit :


ça a un rapport avec le codage little endian/big endian ?  
 

theshockwave a écrit :


par convention, l'endianness sur les réseaux est en big endian. Si tu fais ta petite tambouille dans ton coin et que ton appli tourne sur deux machines à toi qui fonctionnent sur la même architecture, ca ne te posera pas de souci de ne pas respecter cette convention. Par contre, si tu dois communiquer avec de vrais clients, ca risque des les agacer de recevoir des données qui sont juste des tableaux de caractères qui représentent des entier dans ton endianness à toi.
 
Qui plus est, effectivement, le padding de tes structures est à prendre en compte. Je ne peux qu'appuyer le conseil qu'on t'a fait précédemment, à savoir : utiliser sizeof.



theshockwave a bien résumé le truc. Et malgré ça, même utiliser sizeof ne règle pas tous les problèmes. Parce que si la structure est codée d'une certaine façon sur l'ordi de départ (par exemple le padding est au tout début) et que sur l'ordi d'arrivée elle est codée différemment (avec par exemple padding à la fin), ben flipflap la girafe quoi.
La méthode préconisée pour sérializer une structure sur un réseau est de sérializer chacun de ses éléments. Et si certains éléments sont des int ou des long, alors il faut les convertir en entier "réseau" avant de les envoyer en utilisant les fonctions htons (host to net short) ou htonl (host to net long) selon le nombre. Et de l'autre coté, on récupère les nombres en utilisant ntohs (net to host short) ou ntohl (net to host long).


Message édité par Sve@r le 22-07-2010 à 19:50:27

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 22-07-2010 à 19:13:33    

à noter d'ailleurs que l'endianness des floats est incertaine ...
 


---------------
last.fm
Reply

Marsh Posté le 22-07-2010 à 19:37:07    

theshockwave a écrit :

à noter d'ailleurs que l'endianness des floats est incertaine ...
 


 
Je m'étais amusé une fois à coder des fonctions qui jouaient le rôle de htonf, htond, ntohf et ntohd pour gérer le problème des float et des double

Code :
  1. #include <sys/types.h>                        // Types prédéfinis 'c'
  2. #include <netinet/in.h>                        // Socket internet
  3.  
  4. // Fonction de conversion de double "local" en double "réseau"
  5. double htond(
  6.     double hostdbl)                        // Nombre à convertir
  7. {
  8.     // Déclaration des variables
  9.     ushort i;                            // Indice de boucle
  10.     ushort j;                            // Indice de boucle
  11.     ushort convert;                        // Zone de conversion
  12.  
  13.     union {
  14.         double val;                        // Stockage du nombre
  15.         u_char p[8];                    // Décomposition du nombre
  16.     }zone;                            // Zone de travail
  17.  
  18.     // Remplisssage nombre à convertir
  19.     zone.val=hostdbl;
  20.  
  21.     // Travail sur chaque extrémités de la zone en revenant vers le centre
  22.     for (i=0, j=7; i < j; i++, j--)
  23.     {
  24.         // Copie des parties de la zone dans un entier court de conversion
  25.         convert=(zone.p[i] << 8) + zone.p[j];
  26.  
  27.         // Conversion de l'entier court par la primitive normalisée "htons"
  28.         convert=htons(convert);
  29.  
  30.         // Recopie des octets de l'entier court dans les parties de la zone
  31.         zone.p[i]=convert >> 8;
  32.         zone.p[j]=convert & 0x00ff;
  33.     }
  34.  
  35.     // Renvoi nombre converti
  36.     return(zone.val);
  37. }
  38.  
  39. // Fonction de conversion de double "réseau" en double "local"
  40. double ntohd(
  41.     double netdbl)                        // Nombre à convertir
  42. {
  43.     // Déclaration des variables
  44.     ushort i;                            // Indice de boucle
  45.     ushort j;                            // Indice de boucle
  46.     ushort convert;                        // Zone de conversion
  47.  
  48.     union {
  49.         double val;                        // Stockage du nombre
  50.         u_char p[8];                    // Décomposition du nombre
  51.     }zone;                            // Zone de travail
  52.  
  53.     // Remplisssage nombre à convertir
  54.     zone.val=netdbl;
  55.  
  56.     // Travail sur chaque extrémités de la zone en revenant vers le centre
  57.     for (i=0, j=7; i < j; i++, j--)
  58.     {
  59.         // Copie des parties de la zone dans un entier court de conversion
  60.         convert=(zone.p[i] << 8) + zone.p[j];
  61.  
  62.         // Conversion de l'entier court par la primitive normalisée "ntohs"
  63.         convert=ntohs(convert);
  64.  
  65.         // Recopie des octets de l'entier court dans les parties de la zone
  66.         zone.p[i]=convert >> 8;
  67.         zone.p[j]=convert & 0x00ff;
  68.     }
  69.  
  70.     // Renvoi nombre converti
  71.     return(zone.val);
  72. }
  73.  
  74. // Fonction de conversion de float "local" en float "réseau"
  75. float htonf(
  76.     float hostfloat)                        // Nombre à convertir
  77. {
  78.     // Déclaration des variables
  79.     ushort i;                            // Indice de boucle
  80.     ushort j;                            // Indice de boucle
  81.     ushort convert;                        // Zone de conversion
  82.  
  83.     union {
  84.         float val;                        // Stockage du nombre
  85.         u_char p[4];                    // Décomposition du nombre
  86.     }zone;                            // Zone de travail
  87.  
  88.     // Remplisssage nombre à convertir
  89.     zone.val=hostfloat;
  90.  
  91.     // Travail sur chaque extrémités de la zone en revenant vers le centre
  92.     for (i=0, j=3; i < j; i++, j--)
  93.     {
  94.         // Copie des parties de la zone dans un entier court de conversion
  95.         convert=(zone.p[i] << 8) + zone.p[j];
  96.  
  97.         // Conversion de l'entier court par la primitive normalisée "htons"
  98.         convert=htons(convert);
  99.  
  100.         // Recopie des octets de l'entier court dans les parties de la zone
  101.         zone.p[i]=convert >> 8;
  102.         zone.p[j]=convert & 0x00ff;
  103.     }
  104.  
  105.     // Renvoi nombre converti
  106.     return(zone.val);
  107. }
  108.  
  109. // Fonction de conversion de float "réseau" en float "local"
  110. float ntohf(
  111.     float netfloat)                        // Nombre à convertir
  112. {
  113.     // Déclaration des variables
  114.     ushort i;                            // Indice de boucle
  115.     ushort j;                            // Indice de boucle
  116.     ushort convert;                        // Zone de conversion
  117.  
  118.     union {
  119.         float val;                        // Stockage du nombre
  120.         u_char p[4];                    // Décomposition du nombre
  121.     }zone;                            // Zone de travail
  122.  
  123.     // Remplisssage nombre à convertir
  124.     zone.val=netfloat;
  125.  
  126.     // Travail sur chaque extrémités de la zone en revenant vers le centre
  127.     for (i=0, j=3; i < j; i++, j--)
  128.     {
  129.         // Copie des parties de la zone dans un entier court de conversion
  130.         convert=(zone.p[i] << 8) + zone.p[j];
  131.  
  132.         // Conversion de l'entier court par la primitive normalisée "ntohs"
  133.         convert=ntohs(convert);
  134.  
  135.         // Recopie des octets de l'entier court dans les parties de la zone
  136.         zone.p[i]=convert >> 8;
  137.         zone.p[j]=convert & 0x00ff;
  138.     }
  139.  
  140.     // Renvoi nombre converti
  141.     return(zone.val);
  142. }


 
Je ne sais pas ce qu'elles valent en grandeur nature... mais elles fonctionnaient pour envoyer et recevoir des float et des double entre un Unix et un Windows


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 23-07-2010 à 10:40:59    

ce que je voulais dire, c'est qu'il n'y a pas de convention little endian ou big endian pour les floats sur le réseau, donc tu peux les traiter ou non, ca n'a pas d'importance (et d'ailleurs, ce n'est pas parce qu'un processeur est en little endian que les floats sont nécessairement traités en little endian aussi)
 
Du coup, il n'y a pas de htonf qui tienne vraiment la route


---------------
last.fm
Reply

Marsh Posté le 06-10-2011 à 14:11:22    

theshockwave a écrit :


 
par convention, l'endianness sur les réseaux est en big endian. Si tu fais ta petite tambouille dans ton coin et que ton appli tourne sur deux machines à toi qui fonctionnent sur la même architecture, ca ne te posera pas de souci de ne pas respecter cette convention. Par contre, si tu dois communiquer avec de vrais clients, ca risque des les agacer de recevoir des données qui sont juste des tableaux de caractères qui représentent des entier dans ton endianness à toi


 
Up, salut en fait j'aurais une question relative à ce sujet, par rapport à ce que tu me dis
 
Si ma machine/proc est en little endian et que je veux envoyer des données sur le reseau, je dois faire une conversion en Big Endian avant, c'est ça ? Ou est ce que c'est le réseau qui le fait pour moi ?
 
Par ailleurs si je suis sur une machine little endian, est ce que je dois forcément décoder les donnés codées sur plusieurs octets et les remettre en Little endian ?
 
Merci par avance

Reply

Marsh Posté le 06-10-2011 à 21:51:07    


Bigre, 14 mois plus tard... Heureusement que je suis averti par email sinon serais jamais revenu voir...
 

in_your_phion a écrit :

salut en fait j'aurais une question relative à ce sujet, par rapport à ce que tu me dis
 
Si ma machine/proc est en little endian et que je veux envoyer des données sur le reseau, je dois faire une conversion en Big Endian avant, c'est ça ? Ou est ce que c'est le réseau qui le fait pour moi ?


 
Le réseau ne fait aucune conversion. Il transmet ce qu'on lui donne et point barre.
1) Tu dois convertir ton nombre en nombre "réseau" via une primitive "htons()" (Host to Net Short) ou "htonl()" (Host to Net Long) selon le nombre d'origine (short ou long)
2) tu transmets le nombre converti à ton destinataire
3) le destinataire reçoit un nombre "réseau" et le reconverti en nombre local via une primitive "ntohs()" (Net to Host Short) ou "ntohl()" (Net to Host Long)
 
 

in_your_phion a écrit :

Par ailleurs si je suis sur une machine little endian, est ce que je dois forcément décoder les donnés codées sur plusieurs octets et les remettre en Little endian ?


Forcément. Mais la procédure ci-dessus est rodée pour ça...

Message cité 1 fois
Message édité par Sve@r le 06-10-2011 à 21:51:35

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 07-10-2011 à 07:21:34    

<digression> Juste pour rebondir sur le fait que, en C++, boost::fusion permet d'iterer sur les membres d'une structures arbitraires a la façon d'un tuple générique</digression>

Reply

Marsh Posté le 07-10-2011 à 17:27:51    

Sve@r a écrit :


Bigre, 14 mois plus tard... Heureusement que je suis averti par email sinon serais jamais revenu voir...
 


 
 [:tinostar]  
 

Sve@r a écrit :


Forcément. Mais la procédure ci-dessus est rodée pour ça...


 
mERCI ! dOnc on pourrais résumé en disant que tout ce qui sors vers le net doit être converti en big endian, et tout ce qui arrive est supposé être du big endian, c'est ça ?

Reply

Marsh Posté le 07-10-2011 à 23:45:01    

in_your_phion a écrit :

mERCI ! dOnc on pourrais résumé en disant que tout ce qui sors vers le net doit être converti en big endian, et tout ce qui arrive est supposé être du big endian, c'est ça ?


 
Je ne sais pas si le nombre qui sort de htons()/htonl() est du big-endian mais c'est l'idée. Effectivement l'important c'est que tout le monde adopte la même politique et que tout le monde sache qu'il reçoit via réseau un nombre standardisé (si tu penses qu'il est "big-endian" pourquoi pas...) et les fonctions ntohs()/ntohl() (qui sont locales à chaque plateforme) s'occupent du reste...


Message édité par Sve@r le 07-10-2011 à 23:46:02

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 08-10-2011 à 00:59:38    


 

in_your_phion a écrit :


 
mERCI ! dOnc on pourrais résumé en disant que tout ce qui sors vers le net doit être converti en big endian, et tout ce qui arrive est supposé être du big endian, c'est ça ?


 
la convention du net est de transmettre du big endian. Après, si tu as envie de faire le malin et de transmettre du little endian, tant que c'est en environnement contrôlé, pourquoi pas. C'est une convention, pas une obligation. Mais évidemment, les protocols standardisés respecteront certainement cette convention.


---------------
last.fm
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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