Функции класса ntohl/htonl и 64-битные значения
Как известно, порядок байтов в целых числах, представленных более чем одним байтом, может быть разным на разных компьютерах. Существуют компьютерные системы, в которых старший байт числа имеет меньший адрес, чем младший байт (это так называемый порядок байтов с обратным порядком байтов), и есть компьютерные системы, в которых старший байт числа имеет более высокий адрес. чем младший байт (порядок байтов с прямым порядком байтов). При передаче целочисленных числовых данных от машины с одним порядком байтов к машине с другим порядком байтов мы можем ошибаться в интерпретации этой информации. Чтобы избежать этого, было введено понятие сетевого порядка байтов, т. е. порядка байтов, в котором должна быть представлена числовая информация при передаче по сети (был выбран порядок байтов с обратным порядком байтов). Целочисленные числовые данные преобразуются из порядка байтов, принятого на компьютере-отправителе, в сетевой порядок байтов пользовательским процессом, затем они передаются по сети и преобразуются в порядок байтов, принятый на компьютере-получателе, процессом-получателем. . Для преобразования целых чисел из машинного порядка в сетевой и обратно используются четыре функции: htons(), htonl(), ntohs(), ntohl().
Описание функции:
- Функция htonl преобразует целое число из порядка байтов, принятого на компьютере, в сетевой порядок байтов.
- Функция htons преобразует целое короткое число из порядка байтов, принятого на компьютере, в сетевой порядок байтов.
- Функция ntohl преобразует целое число из сетевого порядка байтов в порядок байтов, принятый на компьютере.
- Функция ntohs преобразует целое короткое число из сетевого порядка байтов в порядок байтов, принятый на компьютере.
Перечисленные нами функции работают с 16-битными и 32-битными значениями. С появлением 64-битных систем возникла необходимость реализации функций для работы с 64-битными числами. В некоторых системах для этого существуют функции ntohll() и htonll(). Но в некоторых других системах таких функций нет. В этом случае вы можете реализовать этот механизм самостоятельно.
См. обсуждение 64-битный ntohl() в C++?, чтобы узнать о некоторых решениях преобразования 64-битных значений. Вот одно из таких решений.
#define TYP_INIT 0 #define TYP_SMLE 1 #define TYP_BIGE 2 unsigned long long htonll(unsigned long long src) { static int typ = TYP_INIT; unsigned char c; union { unsigned long long ull; unsigned char c[8]; } x; if (typ == TYP_INIT) { x.ull = 0x01; typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE; } if (typ == TYP_BIGE) return src; x.ull = src; c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c; c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c; c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c; c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c; return x.ull; }
использованная литература
- Хуан Карлос Кобас. Основные понятия о порядке байтов.
- Вопрос на Stackoverflow.com. 64-битный ntohl() в C++?
- Википедия. Эндианство.
Статья опубликована с разрешения автора.