, состоит в том, что вызывающий процесс должен передать ей указатель на двоичный адрес. Этот адрес обычно содержится в структуре адреса сокета, поэтому вызывающему процессу необходимо знать формат структуры и семейство адресов. Следовательно, чтобы использовать эту функцию, для IPv4 нужно написать код следующего вида:
Как видите, код становится зависящим от протокола.
Чтобы решить эту проблему, напишем собственную функцию и назовем ее
sock_ntop
. Она получает указатель на структуру адреса сокета, исследует эту структуру и вызывает соответствующую функцию для того, чтобы возвратить формат представления адреса.
Возвращает: непустой указатель, если функция выполнена успешно, NULL в случае ошибки
sockaddr
указывает на структуру адреса сокета, длина которой равна значению
addrlen
. Функция
sock_ntop
использует свой собственный статический буфер для хранения результата и возвращает указатель на этот буфер.
Формат представления — либо точечно-десятичная форма записи адреса IPv4, либо шестнадцатеричная форма записи адреса IPv6, за которой следует завершающий символ (мы используем точку, как в программе
netstat
), затем десятичный номер порта, а затем завершающий нуль. Следовательно, размер буфера должен быть равен как минимум
INET_ADDRSTRLEN
плюс 6 байт для IPv4 (16 + 6 - 22) либо
INET6_ADDRSTRLEN
плюс 6 байт для IPv6 (46 + 6 - 52).
ПРИМЕЧАНИЕ
Обратите внимание, что при статическом хранении результата функция не допускает повторного вхождения (не является повторно входимой) и не может быть использована несколькими программными потоками (не является безопасной в многопоточной среде — thread-safe). Более подробно мы поговорим об этом в разделе 11.18. Мы допустили такое решение для этой функции, чтобы ее было легче вызывать из простых программ, приведенных в книге.
В листинге 3.8 представлена часть исходного кода, обрабатывающая семейство