Учебники

Unix Socket — сетевые байтовые порядки

К сожалению, не все компьютеры хранят байты, содержащие многобайтовое значение, в одном и том же порядке. Рассмотрим 16-битный интернет, который состоит из 2 байтов. Есть два способа сохранить это значение.

  • Little Endian — в этой схеме байт младшего разряда сохраняется по начальному адресу (A), а байт старшего разряда сохраняется по следующему адресу (A + 1).

  • Big Endian — в этой схеме старший байт сохраняется по начальному адресу (A), а младший байт сохраняется по следующему адресу (A + 1).

Little Endian — в этой схеме байт младшего разряда сохраняется по начальному адресу (A), а байт старшего разряда сохраняется по следующему адресу (A + 1).

Big Endian — в этой схеме старший байт сохраняется по начальному адресу (A), а младший байт сохраняется по следующему адресу (A + 1).

Чтобы позволить машинам с различными соглашениями о порядке следования байтов обмениваться данными друг с другом, протоколы Интернета определяют каноническое соглашение о порядке следования байтов для данных, передаваемых по сети. Это известно как сетевой порядок байтов.

При установлении соединения с интернет-сокетом вы должны убедиться, что данные в членах sin_port и sin_addr структуры sockaddr_in представлены в сетевом порядке байтов.

Функции упорядочения байтов

Процедуры для преобразования данных между внутренним представлением хоста и сетевым порядком байтов:

функция Описание
htons () Короткое замыкание в сети
Htonl () Хост к сети долго
ntohl () Сеть к хосту Лонг
ntohs () Короткая сеть к хосту

Ниже перечислены некоторые подробности об этих функциях —

  • unsigned short htons (unsigned short hostshort) — эта функция преобразует 16-битные (2-байтовые) величины из байтового порядка хоста в сетевой байтовый порядок.

  • unsigned long htonl (unsigned long hostlong) — эта функция преобразует 32-битные (4-байтовые) величины из байтового порядка хоста в сетевой байтовый порядок.

  • unsigned short ntohs (unsigned short netshort) — эта функция преобразует 16-битные (2-байтовые) величины из сетевого байтового порядка в хостовый.

  • unsigned long ntohl (unsigned long netlong) — эта функция преобразует 32-битные величины из сетевого байтового порядка в хостовый.

unsigned short htons (unsigned short hostshort) — эта функция преобразует 16-битные (2-байтовые) величины из байтового порядка хоста в сетевой байтовый порядок.

unsigned long htonl (unsigned long hostlong) — эта функция преобразует 32-битные (4-байтовые) величины из байтового порядка хоста в сетевой байтовый порядок.

unsigned short ntohs (unsigned short netshort) — эта функция преобразует 16-битные (2-байтовые) величины из сетевого байтового порядка в хостовый.

unsigned long ntohl (unsigned long netlong) — эта функция преобразует 32-битные величины из сетевого байтового порядка в хостовый.

Эти функции являются макросами и приводят к вставке исходного кода преобразования в вызывающую программу. На машинах с прямым порядком байтов код изменяет значения порядка сетевого байта. На машинах с прямым порядком байтов код не вставляется, так как он не нужен; функции определены как нуль.

Программа для определения порядка байтов хоста

Сохраните следующий код в файле byteorder.c, а затем скомпилируйте его и запустите на своем компьютере.

В этом примере мы сохраняем двухбайтовое значение 0x0102 в коротком целом числе и затем просматриваем два последовательных байта: c [0] (адрес A) и c [1] (адрес A + 1), чтобы определить байт порядок.

#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);
}

Вывод этой программы на компьютере Pentium выглядит следующим образом: