Это архив сайта coldflame.by.ru, он не обновлялся с 2007 года. Мой современный сайт тут: http://leonid.shevtsov.me.
Домой! Обо мне Специально для РИ-06-1 Разнообразное... барахло, короче :) Программы и прочее Статьи и переводы Блог SmartDaemon
Предыдущая ОглавлениеСледующая

htons(), htonl(), ntohs(), ntohl()

Преобразовать многобайтовые числа в системный или сетевой порядок байт

Прототипы

#include <netinet/in.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

Описание

Чтобы совсем испортить тебе жизнь, разные компьютеры используют разный порядок байт для внутреннего представления многобайтовых чисел (т.е. целых чисел, больших, чем char.) Проблема в том, что если ты перешлешь двухбайтовый short int с компьютера Intel на Mac (в смысле, пока Apple не стали применять процессоры Intel), то число, что один считает 1, другой поймет как 256, и наоборот.

Решение этой проблемы: все споры были забыты, люди решили, что Motorola и IBM все сделали правильно, а в Intel что-то напутали, и теперь в сети все числа передаются в формате "big-endian". Поскольку Intel применяет формат "little-endian", то политкорректно было назвать "big-endian" просто "Сетевым порядком байт". А эти функции преобразовывают числа из местного, системного порядка в сетевой, и наоборот.

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

Типы данных, которые нужно переворачивать, это 32-битное целое (как правило, int) и 16-битное целое ( как правило, short). 64-битные машины могут иметь и htonll() для 64-битных целых, но я ни разу такого не видел. Возможно, такую функцию нужно писать вручную.

В общем, эти функции работают так: сначала ты решаешь откуда преобразуешь число. Если из системного порядка ("host"), первая буква имени "h". Иначе - "n" ("network"). Дальше - "to" ("в"), потом буква, показывающая, куда ты преобразуешь, и последняя буква указывает тип данных, "s" (short) или "l" (long=int). Таким образом:

htons()

host to network short

htonl()

host to network long

ntohs()

network to host short

ntohl()

network to host long

Возвращаемое значение

Все функции возвращают преобразованное значение.

Пример

uint32_t some_long = 10;
uint16_t some_short = 20;

uint32_t network_byte_order;

// преобразовываем и отсылаем
network_byte_order = htonl(some_long);
send(s, &network_byte_order, sizeof(uint32_t), 0);

some_short == ntohs(htons(some_short)); // это выражение истинно


Предыдущая ОглавлениеСледующая