Строку, возвращенную функцией gai_strerror(), можно использовать как часть сообщения об ошибке, выводимого приложением.
55.10.4. Функция getnameinfo()
Функция getnameinfo() является противоположностью функции getaddrinfo(). При передаче ей структуры с адресом сокета (в формате IPv4 или IPv6) она вернет строку с именами соответствующих узла и службы или их числовой эквивалент, если не удается найти соответствия.
#include
#include
int getnameinfo(const struct sockaddr *
size_t
Возвращает 0 при успешном завершении или ненулевое значение при ошибке
Аргумент addr представляет собой указатель на структуру с адресом сокета, которую нужно преобразовать. Размер ее задается с помощью аргумента addrlen. Обычно значения этих аргументов можно получить из вызовов accept(), recvfrom(), getsockname() или getpeername().
Итоговые имена узла и службы возвращаются в виде строк с нулевым символом в конце, на которые указывают аргументы host и service. Эти строки хранятся в буферах и должны быть выделены вызывающим процессом; их размеры следует передавать с помощью аргументов hostlen и servlen. В заголовочном файле
Если нам не нужно имя узла, то аргументу host можно присвоить значение NULL, а hostlen передать 0. Аналогично, если нас не интересует имя службы, то аргументам service и servlen можно присвоить значения NULL и соответственно 0. При этом хотя бы один аргумент, host или service, должен иметь ненулевое значение (то же самое касается соответствующего аргумента, обозначающего длину).
Последний аргумент, flags, представляет собой битовую маску, которая влияет на поведение функции getnameinfo(). Маска формируется путем применения побитового ИЛИ к следующим значениям.
• NI_DGRAM — по умолчанию функция getnameinfo() возвращает имя, связанное со службой
• NI_NAMEREQD — по умолчанию, если имя узла не удается найти, то вместо него возвращается числовой адрес. Указание флага NI_NAMEREQD повлечет ошибку EAI_NONAME.
• NI_NOFQDN — по умолчанию возвращается полное доменное имя узла. Если указать флаг NI_NOFQDN, то получим только первую часть имени, то есть имя конкретного компьютера (при условии, что он подключен к нашей локальной сети).
• NI_NUMERICHOST — делает так, что строка с адресом возвращается в аргументе host. Это бывает удобно в том случае, если мы хотим избежать запроса к DNS-серверу, который может занять довольно много времени.
• NI_NUMERICSERV — способствует возвращению строки с десятичным представлением номера порта в аргументе service. Это может пригодиться, когда мы знаем, что заданный порт не соответствует имени службы (например, если это динамический порт, присвоенный сокету ядром), и нам не хочется лишний раз выполнять поиск по файлу /etc/services.
При успешном завершении функция getnameinfo() возвращает 0, в случае ошибки — один из ненулевых кодов, описанных в табл. 55.1.
Знания, приобретенные в предыдущих разделах, позволяют нам рассмотреть простое клиент-серверное приложение на основе TCP-сокетов. Задача, выполняемая этим приложением, аналогична той, которую решает клиент-серверная программа из раздела 44.8, использующая очередь FIFO: передача клиентам уникальной последовательности чисел (или диапазонов таких последовательностей).