Если при использовании аргумента типа «значение-результат» для длины структуры структура адреса сокета имеет фиксированную длину (см. рис. 3.1), то значение, возвращаемое ядром, будет всегда равно этому фиксированному размеру: 16 для
sockaddr_in
IPv4 и 24 для
sockaddr_in6
IPv6. Для структуры адреса сокета переменной длины (например,
sockaddr_un
домена Unix) возвращаемое значение может быть меньше максимального размера структуры (вы увидите это в листинге 15.2).
Мы говорили о структурах адресов сокетов, передаваемых между процессом и ядром. Для такой реализации, как 4.4BSD, где все функции сокетов являются системными вызовами внутри ядра, это верно. Но в некоторых реализациях, особенно в System V, функции сокетов являются лишь библиотечными функциями, которые выполняются как часть обычного пользовательского процесса. То, как эти функции взаимодействуют со стеком протоколов в ядре, относится к деталям реализации, которые обычно нас не волнуют. Тем не менее для простоты изложения мы будем продолжать говорить об этих структурах как о передаваемых между процессом и ядром такими функциями, как bind и connect. (В разделе В.1 вы увидите, что реализации System V действительно передают пользовательские структуры адресов сокетов между процессом и ядром, но как часть сообщений потоков STREAMS.)
Существует еще две функции, передающие структуры адресов сокетов: это recvmsg и sendmsg (см. раздел 14.5). Однако при их вызове поле длины не является отдельным аргументом функции, а передается как одно из полей структуры.
В сетевом программировании наиболее общим примером аргумента типа «значение-результат» может служить длина возвращаемой структуры адреса сокета. Вы встретите и другие аргументы типа «значение-результат»:
Три средних аргумента функции
select
(раздел 6.3).
Аргумент «длина» для функции
getsockopt
(см. раздел 7.2).
Элементы
msg_namelen
и
msg_controllen
структуры
msghdr
при использовании с функцией
recvmsg
(см. раздел 14.5).
Элемент
ifc_len
структуры
ifconf
(см. листинг 17.1).
Первый из двух аргументов длины в функции
sysctl
(см. раздел 18.4).
3.4. Функции определения порядка байтов
Рассмотрим 16-разрядное целое число, состоящее из двух байтов. Возможно два способа хранения этих байтов в памяти. Такое расположение, когда первым идет младший байт, называется
Рис. 3.4. Прямой и обратный порядок байтов для 16-разрядного целого числа
Сверху на этом рисунке изображены адреса, возрастающие справа налево, а снизу — слева направо.
Термины «прямой порядок байтов» и «обратный порядок байтов» указывают, какой конец многобайтового значения — младший байт или старший — хранится в качестве начального адреса значения.
К сожалению, не существует единого стандарта порядка байтов, и можно встретить системы, использующие оба формата. Способ упорядочивания байтов, используемый в конкретной системе, мы называем
Листинг 3.5. Программа для определения порядка байтов узла
//intro/byteorder.c
1 #include "unp.h"
2 int