Unix Socket - Ordini di byte di rete
Sfortunatamente, non tutti i computer memorizzano i byte che comprendono un valore multibyte nello stesso ordine. Considera una connessione Internet a 16 bit composta da 2 byte. Esistono due modi per memorizzare questo valore.
Little Endian - In questo schema, il byte di ordine inferiore viene memorizzato sull'indirizzo iniziale (A) e il byte di ordine superiore viene memorizzato sull'indirizzo successivo (A + 1).
Big Endian - In questo schema, il byte di ordine superiore viene memorizzato sull'indirizzo iniziale (A) e il byte di ordine inferiore viene memorizzato sull'indirizzo successivo (A + 1).
Per consentire a macchine con diverse convenzioni di ordine dei byte di comunicare tra loro, i protocolli Internet specificano una convenzione canonica di ordine dei byte per i dati trasmessi sulla rete. Questo è noto come Network Byte Order.
Quando si stabilisce una connessione socket Internet, è necessario assicurarsi che i dati nei membri sin_port e sin_addr della struttura sockaddr_in siano rappresentati in Network Byte Order.
Funzioni di ordinamento dei byte
Le routine per la conversione dei dati tra la rappresentazione interna di un host e Network Byte Order sono le seguenti:
Funzione | Descrizione |
---|---|
htons () | Host to Network Short |
htonl () | Host to Network Long |
ntohl () | Rete per ospitare a lungo |
ntohs () | Rete per ospitare breve |
Di seguito sono elencati alcuni dettagli in più su queste funzioni:
unsigned short htons(unsigned short hostshort) - Questa funzione converte le quantità a 16 bit (2 byte) dall'ordine di byte dell'host all'ordine di byte di rete.
unsigned long htonl(unsigned long hostlong) - Questa funzione converte le quantità a 32 bit (4 byte) dall'ordine di byte dell'host all'ordine di byte di rete.
unsigned short ntohs(unsigned short netshort) - Questa funzione converte le quantità a 16 bit (2 byte) dall'ordine dei byte di rete all'ordine dei byte host.
unsigned long ntohl(unsigned long netlong) - Questa funzione converte le quantità a 32 bit dall'ordine dei byte di rete all'ordine dei byte host.
Queste funzioni sono macro e determinano l'inserimento del codice sorgente di conversione nel programma chiamante. Sulle macchine Little Endian, il codice cambierà i valori intorno all'ordine dei byte di rete. Sulle macchine big-endian, non viene inserito alcun codice poiché non è necessario; le funzioni sono definite come null.
Programma per determinare l'ordine dei byte host
Conserva il codice seguente in un file byteorder.c, quindi compilarlo ed eseguirlo sulla tua macchina.
In questo esempio, memorizziamo il valore a due byte 0x0102 nel numero intero corto e quindi guardiamo i due byte consecutivi, c [0] (l'indirizzo A) ec [1] (l'indirizzo A + 1) per determinare il byte ordine.
#include <stdio.h>
int main(int argc, char **argv) {
union {
short s;
char c[sizeof(short)];
}un;
un.s = 0x0102;
if (sizeof(short) == 2) {
if (un.c[0] == 1 && un.c[1] == 2)
printf("big-endian\n");
else if (un.c[0] == 2 && un.c[1] == 1)
printf("little-endian\n");
else
printf("unknown\n");
}
else {
printf("sizeof(short) = %d\n", sizeof(short));
}
exit(0);
}
Un output generato da questo programma su una macchina Pentium è il seguente:
$> gcc byteorder.c
$> ./a.out
little-endian
$>