2010-03-01 15 views
5

Mi è sempre stato insegnato che se un numero intero è maggiore di un carattere, è necessario risolvere il problema di ordinamento dei byte. Di solito, lo avvolgo solo nella hton [l | s] e lo converto indietro con ntoh [l | s]. Ma sono confuso perché questo non si applica ai caratteri a byte singolo.Conversione ordine byte di rete con "char"

Sono stufo di chiedermi perché questo è, e mi piacerebbe un programmatore di reti esperto per aiutarmi a far luce sul motivo per cui gli ordini di byte si applicano solo per interi multibyte.

Rif: http://beej.us/guide/bgnet/output/html/multipage/htonsman.html

+1

Apprezzate le risposte, aveva uno di quei "do'h "momenti! – Rev316

risposta

19

Quello che stai cercando è endianness.

Un grande-endian architettura memorizza i byte di un tipo di dati più byte come così:

big-endian

mentre un'architettura little-endian li memorizza in senso inverso:

little-endian

Quando i dati vengono trasferiti da una macchina all'altra, i byte di un singolo tipo di dati devono essere riordinati per corrispondere alla endianità della macchina di destinazione.

Tuttavia, quando un tipo di dati è costituito da un solo byte, , non c'è nulla da riordinare.

+0

+1, ma potresti voler riconsiderare il furto della larghezza di banda di un altro sito. – Bill

+1

@Bill, la politica di Wikipedia sull'hotlinking è su http://commons.wikimedia.org/wiki/Commons:Reusing_content_outside_Wikimedia#Hotlinking - ma wikimedia.org è bloccato qui, quindi non posso leggerlo da solo. Ti dispiacerebbe parafrasarlo? Grazie! –

+1

Oggi ho imparato qualcosa di nuovo, grazie! Hotlinking parafrasato: "Vai ad esso, ma le immagini potrebbero cambiare. Bummer sul blocco. – Bill

4

tuo stack di rete consente di gestire i bit all'interno dei byte correttamente, è necessario riguardare solo te stesso con ottenere i byte nel giusto ordine.

2

Non si legge singoli bit dal filo, solo byte. Indipendentemente dalla endianità, un singolo byte è lo stesso avanti e indietro proprio come la parola "I" è la stessa avanti e indietro.

+0

Molti sistemi ethernet codificano singoli bit - vedi http://en.wikipedia.org/wiki/MLT-3, anche se quelli più veloci sono nibbles. –

4

Esattamente in quanti modi è possibile ordinare i byte in un singolo carattere?

+2

+1 per snark. Per scriverlo: per definizione in C e C++ un char è la più piccola unità di memoria indirizzabile. –

+3

-1 per snark.Conosci la risposta a una domanda che l'OP non ha fatto. Buon per te. Non essere un idiota a riguardo. –

+0

Alleggerisci: l'OP ovviamente conosce l'ordine dei byte e hton ecc. - perché non ne hai bisogno per un byte è solo uno di quei momenti d'oh. –

3

È necessario considerare cosa fa ciascuna funzione. Da ciò, è necessario applicare tale conoscenza alla dimensione del tipo che si intende modificare. Si consideri il seguente:

#include <stdio.h> 
#include <netinet/in.h> 

int main() { 
    uint16_t i = 42; 
    uint8_t c = 42; // a char 
    printf ("(uint16_t) %08X (%d)\n", i, i); 
    printf ("( htons) %08X (%d)\n", htons(i), htons(i)); 
    printf ("(uint8_t) %08X (%c)\n", c, c); 
    printf ("( htons) %08X (%c)\n", htons(c), htons(c)); 
    return 0; 
} 

(uint16_t) 0000002A (42) 
( htons) 00002A00 (10752) 
(uint8_t) 0000002A (*) 
( htons) 00002A00() 
0

In aggiunta a tutti gli altri modi persone hanno messo: Endianness è sull'ordine dei byte in un numero intero, non l'ordine dei bit in un byte. L'ordine dei bit in un byte è lo stesso anche per le macchine big-endian e little-endian. L'unica differenza è l'ordine in cui i byte stessi vengono utilizzati per memorizzare un numero intero (o breve o what-have-you). E così perché c'è un solo byte in un char, non c'è differenza nel modo in cui quel valore è immagazzinato, sia in un'architettura big-endian o little-endian.

+0

Anche se eseguo calcoli come bit per bit o aggiunte * (carattere firmato) *? Questo è per convertire punti di codice Unicode contenuti in interi in ᴜᴛꜰ-8. – user2284570

0

codice EZPZ è corretto ..

uint16_t i = 65534; 
printf ("(uint16_t) %08X (%d)\n", i, i); 

Returns... 
(uint16_t) 0000FFFE (-2) 

È necessario utilizzare un unsigned int, invece così non è interpretato come un firmato int

uint16_t i = 65534; 
printf ("(uint16_t) %08X (%u)\n", i, i); 

Returns... 
(uint16_t) 0000FFFE (65534)