Читаем UNIX: разработка сетевых приложений полностью

 3 main(int argc, char **argv)

 4 {

 5  union {

 6   short s;

 7   char c[sizeof(short)];

 8  } un;

 9  un.s = 0x0102;

10  printf("%s: ", CPU_VENDOR_OS);

11  if (sizeof(short) == 2) {

12   if (un.c[0] == 1 && un.c[1] == 2)

13    printf("big-endian\n");

14   else if (un.c[0] == 2 && un.c[1] == 1)

15    printf("little-endian\n");

16   else

17    printf("unknown\n");

18  } else

19   printf('sizeof(short) = %d\n", sizeof(short));

20  exit(0);

21 }

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

Константа CPU_VENDOR_OSопределяется программой GNU (аббревиатура «GNU» раскрывается рекурсивно — GNU's Not Unix) autoconfв процессе конфигурации, необходимой для выполнения программ из этой книги. В этой константе хранится тип центрального процессора, а также сведения о производителе и реализации операционной системы. Ниже представлены некоторые примеры вывода этой программы при запуске ее в различных системах (см. рис. 1.7).

freebsd4 % byteorder

i386-unknown-freebsd4.8: little-endian

macosx % byteorder

powerpc-apple-darwin6.6: big-endian

freebsd5 % byteorder

sparc64-unknown-freebsd5.1: big-endian

aix % byteorder

powerpc-ibm-aix5.1.0.0: big-endian

hpux % byteorder

hppa1.1-hp-ux11 11: big-endian

linux % byteorder

i586-pc-linux-gnu: little-endian

solaris % byteorder

sparc-sun-solaris2.9: big-endian

Все, что было сказано об определении порядка байтов 16-разрядного целого числа, конечно, справедливо и в отношении 32-разрядного целого.

ПРИМЕЧАНИЕ

Существуют системы, в которых возможен переход от прямого к обратному порядку байтов либо при перезапуске системы (MIPS 2000), либо в любой момент выполнения программы (Intel i860).

Разработчикам сетевых приложений приходится обрабатывать различия в определении порядка байтов, поскольку в сетевых протоколах используется сетевой порядок байтов( network byte order). Например, в сегменте TCP есть 16- разрядный номер порта и 32-разрядный адрес IPv4. Стеки отправляющего и принимающего протоколов должны согласовывать порядок, в котором передаются байты этих многобайтовых полей. Протоколы Интернета используют обратный порядок байтов.

Теоретически реализация Unix могла бы хранить поля структуры адреса сокета в порядке байтов узла, а затем выполнять необходимые преобразования при перемещении полей в заголовки протоколов и обратно, позволяя нам не беспокоиться об этом. Но исторически и с точки зрения POSIX определяется, что для некоторых полей в структуре адреса сокета порядок байтов всегда должен быть сетевым. Поэтому наша задача — выполнить преобразование из порядка байтов узла в сетевой порядок и обратно. Для этого мы используем следующие четыре функции:

#include

uint16_t htons(uint16_t host16bitvalue);

uint32_t htonl(uint32_t host32bitvalue);

Обе функции возвращают значение, записанное в сетевом порядке байтов

uint16_t ntohs(uint16_t net16bitvalue);

uint32_t ntohl(uint32_t net32bitvalue);

Обе функции возвращают значение, записанное в порядке байтов узла

В названиях этих функций hобозначает узел, nобозначает сеть, s— тип short, l — тип long. Термины shortи longявляются наследием времен реализации 4.2BSD Digital VAX. Следует воспринимать sкак 16-разрядное значение (например, номер порта TCP или UDP), а l— как 32-разрядное значение (например, адрес IPv4). В самом деле, в 64-разрядной системе Digital Alpha длинное целое занимает 64 разряда, а функции htonlи ntohlоперируют 32-разрядными значениями (несмотря на то, что используют тип long).

Перейти на страницу:

Похожие книги

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

В книге собраны и обобщены советы по решению различных проблем, которые рано или поздно возникают при эксплуатации как экономичных нетбуков, так и современных настольных моделей. Все приведенные рецепты опробованы на практике и разбиты по темам: аппаратные средства персональных компьютеров, компьютерные сети и подключение к Интернету, установка, настройка и ремонт ОС Windows, работа в Интернете, защита от вирусов. Рассмотрены не только готовые решения внезапно возникающих проблем, но и ответы на многие вопросы, которые возникают еще до покупки компьютера. Приведен необходимый минимум технических сведений, позволяющий принять осознанное решение.Компакт-диск прилагается только к печатному изданию книги.

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT