Gniazdo Unix - kolejność bajtów w sieci
Niestety nie wszystkie komputery przechowują bajty zawierające wartość wielobajtową w tej samej kolejności. Rozważmy 16-bitowy Internet, który składa się z 2 bajtów. Istnieją dwa sposoby przechowywania tej wartości.
Little Endian - W tym schemacie młodszy bajt jest przechowywany pod adresem początkowym (A), a najstarszy bajt jest przechowywany pod następnym adresem (A + 1).
Big Endian - W tym schemacie najstarszy bajt jest przechowywany pod adresem początkowym (A), a najmniejszy bajt jest przechowywany pod następnym adresem (A + 1).
Aby umożliwić komunikację między maszynami o różnych konwencjach kolejności bajtów, protokoły internetowe określają kanoniczną konwencję kolejności bajtów dla danych przesyłanych w sieci. Jest to znane jako kolejność bajtów w sieci.
Podczas ustanawiania połączenia internetowego przez gniazdo należy upewnić się, że dane w elementach sin_port i sin_addr struktury sockaddr_in są reprezentowane w sieciowej kolejności bajtów.
Funkcje porządkowania bajtów
Procedury konwersji danych między wewnętrzną reprezentacją hosta a kolejnością bajtów sieci są następujące -
Funkcjonować | Opis |
---|---|
htons () | Host do sieci Short |
htonl () | Host do sieci długo |
ntohl () | Sieć do hostowania długo |
ntohs () | Sieć do hostowania Short |
Poniżej znajduje się więcej szczegółów na temat tych funkcji -
unsigned short htons(unsigned short hostshort) - Ta funkcja konwertuje wartości 16-bitowe (2-bajtowe) z kolejności bajtów hosta na kolejność bajtów sieci.
unsigned long htonl(unsigned long hostlong) - Ta funkcja konwertuje wielkości 32-bitowe (4-bajtowe) z kolejności bajtów hosta na kolejność bajtów sieci.
unsigned short ntohs(unsigned short netshort) - Ta funkcja konwertuje wartości 16-bitowe (2-bajtowe) z sieciowej kolejności bajtów na kolejność bajtów hosta.
unsigned long ntohl(unsigned long netlong) - Ta funkcja konwertuje ilości 32-bitowe z kolejności bajtów sieci na kolejność bajtów hosta.
Funkcje te są makrami i powodują wstawienie kodu źródłowego konwersji do programu wywołującego. Na maszynach little-endian kod zmieni wartości na sieciową kolejność bajtów. Na maszynach typu big-endian żaden kod nie jest wstawiany, ponieważ nie jest potrzebny; funkcje są zdefiniowane jako null.
Program do określania kolejności bajtów hosta
Zachowaj następujący kod w pliku byteorder.c, a następnie skompiluj go i uruchom na swoim komputerze.
W tym przykładzie przechowujemy dwubajtową wartość 0x0102 w krótkiej liczbie całkowitej, a następnie patrzymy na dwa kolejne bajty, c [0] (adres A) ic [1] (adres A + 1), aby określić bajt zamówienie.
#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);
}
Dane wyjściowe generowane przez ten program na komputerze z procesorem Pentium są następujące -
$> gcc byteorder.c
$> ./a.out
little-endian
$>