Разработчики 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) ;
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.