Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
чтиво_ч3.doc
Скачиваний:
4
Добавлен:
15.11.2019
Размер:
435.2 Кб
Скачать

И снова dns

В прошлой части статьи говорилось о том, что для соединения socket’а с сервером Вы можете использовать функцию connect, но эта функция требует структуру sockaddr (или sockaddr_in в случае TCP/IP). Как нам получить эту структуру? Sockaddr_in требует адресное семейство, IP адрес и порт сервера. Адресное семейство понятно - AF_INET, порт тоже не трудно указать (порт по умолчанию для HTTP протокола, 80), а вот как быть с IP адресом, если мы знаем только название сайта, куда мы хотим подключиться? Помните, я говорил про DNS? Вот тут как раз в дело вступает эта система. Что бы узнать адрес сервера достаточно воспользоваться функцией gethostbyname: hostent * gethostbyname(const char *name);

В функцию вы передаете строку с названием сайта (например, www.vr-online.ru), а функция вернет указатель на структуру hostent. В этой структуре будет содержаться список адресов, доступных для данного сайта. Один из этих адресов можно подставить в структуру sockaddr_in и будет Вам счастье.

Основа

Программа, которую мы напишем, будет соединяться с сервером, отправлять HTTP HEAD запрос и сохранять все, что пришло в ответ. Сначала определимся с «базой» программы, т.е. с тем, что нам необходимо для корректной работы (да и работы вообще) нашего приложения.

#include <iostream>

#include <winsock2.h>

#include <windows.h>

 

using namespace std;

 

class HeadReqException

{

public:

HeadReqException() :

m_pMessage("") {}

virtual ~HeadReqException() {}

HeadReqException(const char *pMessage) :

m_pMessage(pMessage) {}

const char * what() { return m_pMessage; }

private:

const char *m_pMessage;

};

Большинство WinSock функций включено в библиотеке windows.h, но т.к. мы будем использовать некоторые специализированные функции, то необходимо подключить и winscok2.h. Для чего нужна библиотка iostream и что за строчка «using namespace std;» я объяснять не буду, т.к. делал это ранее в своих статьях. Класс HeadReqException нужен для обработки возникающих ошибок. Один из конструкторов этого класса принимает строку с сообщением ошибки, которая может быть извлечена с помощью функции what(). O спецификаторах доступа и виртуальных функциях я сейчас рассказывать не буду, т.к. это выходит далеко за пределы этого материала и по этим темам можно писать отдельную статью (хотя зачем? множество информации по ним Вы сможете найти в Интернете).

Константы и глобальные переменные

В программе потребуются некоторые константы и глобальные данные, которые описаны в следующем куске кода:

const int REQ_WINSOCK_VER = 2; // Минимальная версия WinSock

const char DEF_SERVER_NAME[] = "www.vr-online.ru";

const int SERVER_PORT = 80;

const int TEMP_BUFFER_SIZE = 128;

 

const char HEAD_REQUEST_PART1[] =

{

"HEAD <a href="http://vr-online.ru/articles">http://vr-online.ru/articles</a> HTTP/1.1\r\n" // Получаем страницу

"Host: " // Определяем имя сервера

};

 

const char HEAD_REQUEST_PART2[] =

{

"\r\n" // Конец строки, содеражщей имя сервера

"User-agent: HeadReqSample\r\n" // Определяем браузер

"Connection: close\r\n" // Закрываем соединение после ответа

"\r\n" // Пустая строка говорит о том, что ответ получен полностью

};

 

typedef unsigned long IPNumber;

Назначение первых четырех переменных понятно из их имени. Далее полный HTTP запрос разбивается на две части, каждая из которых представляет собой массив строк. Изначально массив заполнен. Ну и последняя строка, как и четыре первых, не должна вызывать каких-либо непоняток.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]