Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

107: case IPPROTO_UDP: printf("\tudp");

108: break;

109: case IPPROTO_RAW: printf("\traw");

110: break;

111: default: printf("\t(%d)

112: addr->ai_protocol);

113: break;

114: }

115: else

116: printf("\t");

117:

118: /* отобразить информацию и для IPv4-, и для IPv6-адресов */

119:

120: if (addr->ai_family == PF_INET) {

121: struct sockaddr_in * inetaddr = (void*)addr->ai_addr;

122: char nameBuf[INET_ADDRSTRLEN];

123:

124: if (serviceName)

125: printf("\tпорт%d", ntohs(inetaddr->sin_port));

126:

127: if (hostName)

128: printf("\tхост%s",

129: inet_ntop(AF_INET, &inetaddr->sin_addr,

130: nameBuf, sizeof(nameBuf)));

131: } else if (addr->ai_family == PF_INET6) {

132: struct sockaddr_in6 * inetaddr =

133: (void*)addr->ai_addr;

134: char nameBuf[INET6_ADDRSTRLEN];

135:

136: if (serviceName)

137: printf("\tпорт%d", ntohs(inetaddr->sin6_port));

138:

139: if (hostName)

140: printf("\tхост%s",

141: inet_ntop(AF_INET6, &inetaddr->sin6_addr,

142: nameBuf, sizeof(nameBuf)));

143: }

144:

145: if (addr->ai_canonname)

146: printf("\tname%s", addr->ai_canonname);

147:

148: printf("\n");

149:

150: addr = addr->ai_next;

151: }

152:

153: /* очистить результаты getaddrinfo */

154: freeaddrinfo(result);

155:

156: return 0;

157: }

В отличие от большинства библиотечных функций,

getaddrinfo
возвращает целое число, которое равно нулю в случае успеха, и описывает ошибку в случае неудачи. Такие функции, как правило, не используют
errno
. В табл. 17.3 описаны различные коды ошибок, которые могут возвращать подобные функции.

Таблица 17.3. Ошибки поиска соответствия адреса и имени

Ошибка Описание
EAI_AGAIN
Имя не может быть найдено. Повторный поиск может оказаться успешным.
EAI_BADFLAGS
В функцию переданы недействительные флаги.
EAI_FAIL
В процессе поиска соответствия возникла постоянная ошибка.
EAI_FAMILY
Семейство адресов не распознано.
EAI_MEMORY
Запрос на выделение памяти не выполнен.
EAI_NONAME
Имя или адрес невозможно преобразовать.
EAI_OVERFLOW
Переданный буфер слишком мал.
EAI_SERVICE
Для данного типа сокета служба не существует.
EAI_SOCKTYPE
Был передан недействительный тип сокета.
EAI_SYSTEM
Произошла системная ошибка; сама ошибка содержится в переменной
errno
.

Коды ошибок можно преобразовать в строки, описывающие проблему, с помощью функции

gai_strerror
.

#include <netdb.h>

const char * gai_strerror(int error);

Здесь параметр

error
должен быть ненулевым значением, возвращенным функцией
getaddrinfo
. Если произошла ошибка
EAI_SYSTEM
, то для получения более точного описания программа должна использовать
strerror(errno)
.

17.5.6. Преобразование адресов в имена

К счастью, переводить IP-адреса и номера портов в имена хостов и служб гораздо проще, чем наоборот.

#include <sys/socket.h>

#include <netdb.h>

int getnameinfo(struct sockaddr * addr, socklen_t addrlen,

 char * hostname, size_t hostlen,

 char * servicename, size_tservicelen, intflags);

Здесь параметр

addr
указывает либо на
struct sockaddr_in
, либо на
struct sockaddr_in6
, член
addrlen
содержит размер структуры, на которую указывает
addr
. IP-адрес и номер порта, определенные
addr
, преобразуются в имя хоста, сохраняющееся в ячейке, на которую указывает
hostname
, и в имя службы, сохраняющееся в
servicename
.

  • Читать дальше
  • 1
  • ...
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: