Как известно, порядок байт в целых числах, представление которых занимает более одного байта, может быть для различных компьютеров неодинаковым. Есть вычислительные системы, в которых старший байт числа имеет меньший адрес, чем младший байт (big-endian byte order), а есть вычислительные системы, в которых старший байт числа имеет больший адрес, чем младший байт (little-endian byte order). При передаче целой числовой информации от машины, имеющей один порядок байт, к машине с другим порядком байт мы можем неправильно истолковать принятую информацию. Для того чтобы этого не произошло, было введено понятие сетевого порядка байт, то есть порядка байт, в котором должна представляться целая числовая информация в процессе передачи ее по сети (был выбран big-endian byte order). Целые числовые данные из представления, принятого на компьютере-отправителе, переводятся пользовательским процессом в сетевой порядок байт, в таком виде путешествуют по сети и переводятся в нужный порядок байт на машине-получателе процессом, которому они предназначены. Для перевода целых чисел из машинного представления в сетевое представление и обратно, используются четыре функции: htons(), htonl(), ntohs(), ntohl().
Описание функций:
Перечисленные функции работают с 16-битными и 32-битными значениями. С приходом 64-битных систем повысилась потребность в функциях, работающих с 64-битнымим величинами. В ряде систем для работы с 64-битными значениями появились функции ntohll() и htonll(). Но в ряде систем этих функций нет. В этом случае вы можете сами реализовать необходимую функциональность.
В обсуждении "64 bit ntohl() in 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;
}
0