-
Укрощение Интренет@
Узнать IP-адрес такого-то домена можно с помощью функции «struct hostent FAR * gethostbyname (const char FAR * name);». Функция обращается к DNS и возвращает свой ответ в структуре hostent или нуль если DNS сервер не смог определить IP-адрес данного домена.
Структура hostent выглядит следующим образом:
struct hostent
{
char FAR * h_name; // официальное имя узла
char FAR * FAR* h_aliases; // альтернативные имена узла (массив строк)
short h_addrtype; // тип адреса
short h_length; // длина адреса (как правило AF_INET)
char FAR * FAR * h_addr_list; // список указателей на IP-адреса
// ноль – конец списка
};
Как и в случае с in_addr, во множестве программ и прилагаемых к Winsock SDK примерах активно используется недокументированное поле структуры h_addr. Например, вот строка из файла «simplec.c» «memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);» Заглянув в «winsock2.h» можно найти, что оно обозначает: «#define h_addr h_addr_list[0]«.
А вот это уже интересно! Дело в том, что с некоторыми доменными именами связано сразу несколько IP-адресов. В случае неработоспособности одного узла, клиент может попробовать подключится к другому или просто выбрать узел с наибольшей скоростью обмена. Но в приведенном примере клиент использует только первый IP адрес в списке и игнорирует все остальные! Конечно, это не смертельно, но все же будет лучше, если в своих программах вы будете учитывать возможность подключения к остальным IP-адресам, при невозможности установить соединение с первым.
Функция gethostbyname ожидает на входе только доменные имена, но не цифровые IP-адреса. Между тем, правила «хорошего тона» требуют предоставления клиенту возможности как задания доменных имен, так и цифровых IP-адресов.
Решение заключается в следующем – необходимо проанализировать переданную клиентом строку – если это IP адрес, то передать его функции inet_addr в противном случае – gethostbyaddr, полагая, что это доменное имя. Для отличия IP-адресов от доменных имен многие программисты используют нехитрый трюк: если первый символ строки – цифра, это IP-адрес, иначе – имя домена. Однако, такой трюк не совсем честен – доменные имя могут начинаться с цифры, например, «666.ru», могут они и заканчиваться цифрой, например, к узлу «666.ru» члены cубдомена «666″ могут так и обращаться – «666″. Самое смешное, что (теоретически) могут существовать имена доменов, синтаксически неотличимые от IP-адресов! Поэтому, на взгляд автора данной статьи, лучше всего действовать так: передаем введенную пользователем строку функции inet_addr, если она возвращает ошибку, то вызываем gethostbyaddr.
Для решения обратной задачи – определении доменного имени по IP адресу предусмотрена функция «struct HOSTENT FAR * gethostbyaddr (const char FAR * addr, int len, int type)», которая во всем аналогична gethostbyname, за тем исключением, что ее аргументом является не указатель на строку, содержащую имя, а указатель на четырехбайтовый IP-адрес. Еще два аргумента задают его длину и тип (соответственно, 4 и AF_INET).
Определение имени узла по его адресу бывает полезным для серверов, желающих «в лицо» знать своих клиентов.
Для преобразования IP-адреса, записанного в сетевом формате в символьную строку, предусмотрена функция «char FAR * inet_ntoa (struct in_addr)», которая принимает на вход структуру in_addr, а возвращает указатель на строку, если преобразование выполнено успешно и ноль в противном случае.
Сетевой порядок байт
Среди производителей процессоров нет единого мнения на счет порядка следования младших и старших байт. Так например, у микропроцессоров Intel младшие байты располагаются по меньшим адресам, а у микропроцессоров Motorola 68000 – наоборот. Естественно, это вызывает проблемы при межсетевом взаимодействии, поэтому, был введен специальный сетевой порядок байт, предписывающий старший байт передавать первым (все не так, как у Intel).
Для преобразований чисел из сетевого формата в формат локального хоста и наоборот предусмотрено четыре функции — первые две манипулируют короткими целыми (16-битными словами), а две последние – длинными (32-битными двойными словами): u_short ntohs (u_short netshort); u_short htons (u_short hostshort ); u_long ntohl (u_long netlong ); u_long htonl (u_long hostlong);
Чтобы в них не запутаться, достаточно запомнить, что за буквой «n» скрывается сокращение «network», за «h» – «host» (подразумевается локальный), «s» и «l» соответственно короткое (short) и длинное (long) беззнаковые целые, а «to» и обозначает преобразование.
Страниц: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
Ваш отзыв


