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

Если все прошло успешно, функция connect возвращает ноль. Результат connect отправляется в переменную nConnect, затем ее значение проверяется QFinger. Если значение nConnect свидетельствует о случившейся ошибке, программа завершается, выдав предупреждающее сообщение на экран. Вы знаете, что при создании сокета функцией socket, необходимо указывать тип протокола. Если программе нужно надежное, двухстороннее соединение, указывается SOCK_STREAM, если нужен датаграммный сервис — указывается SOCK_DGRAM. Функция socket возвращает дескриптор сокета.

Функция connect проверяет переданный ей дескриптор, выясняя, с каким типом протоколов она имеет дело. Если выбран потоковый протокол (SOCK_STREAM), connect соединяется с удаленным компьютером. Для датаграммного сокета (SOCK_DGRAM) это излишне, поэтому адрес пункта назначения не устанавливается. Если функция connect отработала успешно, сокет готов к передаче и приему данных от удаленного компьютера.

Как уже неоднократно говорилось, чтобы получить доступ к различным сетевым службам, программе необходимо выполнить последовательность определенных действий. Причем эта последовательность одинакова для большинства программ. После того как вы усвоите, что нужно предпринять, чтобы получить доступ к сетевым службам, вам станет проще создавать свои собственные варианты протоколов и сетевого сервиса.

Возможно, лучший способ узнать, что же все-таки требуется — пройти весь процесс задом наперед, начав с соединенного сокета. Другими словами, чтобы соединить сокет, ему нужно предоставить определенную информацию. Следовательно, нужно рассмотреть эту информацию подробнее и выяснить, откуда она берется. Ниже приведены шаги, которые нужно предпринять, чтобы соединить сокет с удаленным приложением. Шаги приведены в обратном порядке. Вы начинаете с соединенного сокета и следуете назад:

1.   Чтобы соединить сокет, вызывается функция connect. Ее аргументы — дескриптор и адрес сокета.

2.   Чтобы получить дескриптор сокета, вызывается функция socket. Для нее необходимо указать тип сетевого соединения — потоковый или датаграммный. Также можно указать протокол или ограничиться протоколом по умолчанию.

3.   Чтобы создать адрес сокета, необходимо заполнить структуру данных. В ней, в частности, указывается порт протокола и реально существующий IP-адрес удаленного компьютера в формате структуры адреса Интернет.

4.   Чтобы получить номер порта, вызывается функция getservbyname. В качестве аргумента указывается наименование сетевой службы. Дополнительно указывается протокол, либо принимается протокол по умолчанию.

5.   Чтобы получить IP-адрес, вызываются функции для работы с DNS, например gethostbyname или gethostbyaddr.

Посылаем запрос Finger

После того как соединение установлено, мы можем посылать и принимать данные. Функции send для этого задается аргумент — дескриптор сокета, через который мы хотим передать данные. Так выглядит прототип функции send:

int PASCAL FAR send(SOCKET s, const char FAR * buf, int len, int flags) ;

Сокет, через который передаются данные, как уже говорилось, указывается при помощи дескриптора — первого параметра send. Остальные параметры зависят от вашего приложения. Второй является указателем на буфер, в котором хранятся данные для передачи. Третий параметр — длина этого буфера. Четвертый параметр может задаваться специальными флагами, задача которых — изменить поведение сокета при передаче данных. В спецификации Winsock версии 1.1 определено два таких флага: MSG_DONTROUTE и MSG_OOB.

Флаг MSG_DONTROUTE указывает, что сообщение нельзя маршрутизировать. Другими словами, блок передаваемых с этим флагом данных не должен обрабатываться низлежащим сетевым уровнем, ответственным за маршрутизацию обычных сообщений. В спецификации Winsock указано, что этот флаг может игнорироваться реализациями Winsock. Поэтому вам его лучше не употреблять в целях иных, нежели простое тестирование.