Протокол Finger и информация о пользователях, страница 8

Разработчики Winsock ориентировались на то, что Winsock будет обслуживать не только семейство TCP/IP. Поэтому вместе с адресом вы должны указать длину этого адреса и его семейство. Посмотрим, что это значит для вас, как разработчика. Предположим, что вы спроектировали приложение Winsock API для работы в Интернет. Прошло несколько лет, и вам понадобилось перенести его в другую сетевую среду, также поддерживаемую Windows Sockets. Наряду с другими изменениями, вам потребуется модифицировать вызов функции gethostbyaddr.

В функции gethostbyaddr будет необходимо изменить третий параметр (новое семейство протоколов) и, возможно, второй параметр (длина адреса). Библиотека Winsock для новой сети рассмотрит переданные параметры и правильно заполнит структуру с информацией о сетевом компьютере. Теперь предположим, что gethostbyaddr принимает только 32-разрядные адреса, а в новой сети адреса 64-разрядные. В этом случае gethostbyaddr будет просто невозможно пользоваться, а в Winsock придется включать дополнительные функции для работы с другой размерностью адресов.

Предположим, что адреса у новой сети все-таки 32-разрядные, но у них другой порядок байтов. В этом случае в Winsock придется иметь отдельные функции для каждой комбинации «размер адреса — порядок байтов». Представляете себе, что получиться в результате? Так что параметры семейств адресов и протоколов позволяют грамотно обойти трудности, связанные с дальнейшим развитием Winsock.

Вы повстречаете константы AF_INET и PF_INET в большинстве программ, с которыми вам доведется встретиться. AF_INET представляет семейство адресов (AF) Интернет (INET), a PF_INET - семейство протоколов (PF) Интернет. В то же время в спецификации Winsock указано, что эти константы равны. Другими словами, в файле-заголовке Winsock есть следующая строчка:

#define PF_INET   AF_INET

Адрес сокета

QFinger использует переменную sockAddr типа SOCKADDR_IN. SOCKADDR_IN описывает структуру-адрес сокета Интернет. Следующие несколько операторов из QFINGER.CPP заносят необходимую для соединения сокета с удаленным компьютером информацию в переменную sockAddr:

// Формируем адрес сокета

sockAddr.sin_family = AF_INET; // Семейство адресов Интернет

sockAddr.sin_port = iFingerPort;

sockAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);

Семейство адресов AF_INET заносится в поле sin_family структуры sockAddr. Далее поле sin_port получает значение номера порта протокола Finger. Как вы помните, оно берется либо из сетевой базы данных (посредством getservbyname), либо из файла winsock.h, где определено как IPPORT_FINGER. Наконец, элементу sin_addr присваивается IP-адрес, извлеченный из структуры host-entry.

Соединяем сокет

Как только сокету присвоен адрес, он готов к соединению. Соединение происходит при участии функции connect. Вот ее прототип:

int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR * name, int namelen) ;

Вы уже встречались с параметрами функции connect. Первый параметр — дескриптор сокета, полученный от функции socket. Второй параметр — указатель на действительную адресную структуру сокета. Мы уже рассматривали ее структуру подробно. Значения, присвоенные элементам адресной структуры sockAddr, также уже рассматривались. Переменная sockAddr передается функции connect в качестве параметра.

Третий параметр функции connect — длина адресной структуры сокета. Чтобы вычислить длину структуры, QFinger вызывает стандартный оператор языка C/C++ sizeof, а результат передает функции. Ниже приведены операторы, при помощи которых QFinger соединяет сокет:

// Соединяем сокет

nConnect = connect(nSocket, (PSOCKADDR) &sockAddr, sizeof(sockAddr));

if (nConnect)

MessageBox(NULL, "Error connecting socket!!",

PROG_NAME, MB_OK | MB_ICONSTOP) ;