Разработка приложений для Internet

Приложение ConsoleHTTP


В разделе “Приложение Console FTP“ мы привели приложение ConsoleFTP, которое соединяется с заданным сервером FTP. Для этого в нем сначала создается объект класса CInternetSession, представляющий сеанс работы с WinInet, а затем с помощью метода GetFtpConnection предпринимается попытка соединиться с сервером по заданному адресу. Если установить соединение не удается, например, из - за того, что адрес с таким адресом не существует, то метод GetFtpConnection вызывает исключение CInternetException:

// Инициализируем сеанс работы с WinInet

CInternetSession* m_InternetSession = NULL;

m_InternetSession = new CInternetSession("Connecter");  

try

{

   // Пытаемся соединиться с FTP - сервером sServer

   CFtpConnection*  m_FtpConnection = NULL;

        

   m_FtpConnection =

         m_InternetSession -> GetFtpConnection( sServer );

   . . .

}



catch (CInternetException* pEx)

{

      // Обрабатываем исключение CInternetException

      . . .

}

Таким образом, о существовании FTP сервера sServer можно судить по тому, вызвал ли метод GetFtpConnection исключение CInternetException. Если исключение не появилось и метод GetFtpConnection вернул не нулевое значение, значит сервер FTP существует и доступен. А если исключение все же было вызвано, значит, скорее всего, сервера с заданным именем просто не существует.

Как вы знаете, класс CInternetSession содержит в себе три метода для соединения с серверами FTP, WWW и Gopher. Это методы GetFtpConnection, GetHttpConnection и GetGopherConnection. Казалось бы достаточно заменить в исходных текстах приложения FtpConnection вызов метода GetFtpConnection на GetHttpConnection и вы сможете использовать это же приложения для поиска серверов WWW.

Проведите небольшой эксперимент и внесите в исходные тексты проекта FtpConnection соответствующие изменения:

// Инициализируем сеанс работы с WinInet

CInternetSession* m_InternetSession = NULL;

m_InternetSession = new CInternetSession("Connecter");  


try

{

   // Пытаемся соединиться с WWW - сервером sServer

   CHttpConnection*  m_HttpConnection = NULL;

        

   m_HttpConnection =

         m_InternetSession -> GetHttpConnection( sServer );

   . . .

}

catch (CInternetException* pEx)

{

      // Обрабатываем исключение CInternetException

      . . .

}

Постройте проект и запустите полученное приложение. Попытайтесь соединиться с помощью приложения с различными серверами WWW. Очень скоро вы обнаружите что соединение выполняется “успешно” даже с несуществующими серверами.

Чтобы быть уверенным, что сервер WWW по данному адресу не существует или недоступен, вы можете попытаться связаться с ним при помощи любой программы навигатора, например с помощью Microsoft Internet Explorer или Netscape Navigator.

Так, если вы запустите навигатор Microsoft Internet Explorer и попробуете просмотреть с его помощью сервер FTP по адресу http://home.frolov.com/, то скорее всего, получите предупреждающее сообщение, показанное нами на рисунке 3.1. Увы, пока сервера FTP с таким именем не существует.



Рис. 3.1. Сервер http://home.frolov.com/ не найден

Изменим теперь приложение ConsoleFtp так, чтобы оно не только соединялось с сервером WWW, но и запрашивало с него информацию об определенном файле. Создайте новый проект ConsoleHttp таким же образом, как вы создавали проект ConsoleFtp. Укажите что приложение будет использовать библиотеку классов MFC.

Затем создайте новый текстовый файл ConsoleHttp.cpp, наберите в нем программный код, представленный в листинге 3.2 и включите его в проект. Чтобы ускорить набор файла ConsoleHttp.cpp за его основу вы можете взять файл ConsoleFtp.cpp из проекта ConsoleFtp.

Листинг 3.2. Файл ConsoleHttp.cpp

//============================================================

// Приложение ConsoleFtp. Выполняет соединение с заданным

// сервером WWW

//

// (C) Фролов Г.В., 1997

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//         или

//         http://www.dials.ccas.ru/frolov



//============================================================

// Включаемый файл для библиотеки MFC

#include <afx.h>

// Включаемый файл для классов WinInet

#include <afxinet.h>

// Включаемый файл для консольного ввода/вывода

#include <iostream.h>

// Включаемый файл для стандартных функций

#include <stdlib.h>

//============================================================

// Главная функция приложения

//============================================================

int main(int argc, char* argv[])

{

   // Если приложение запущено без параметра, отображаем на

   // экране формат вызова приложения

   if (argc != 2)

   {

      cout << "Programm format: ConsoleFtp <URL>" << endl;

      cout << "  <URL> - URL address of WWW" << endl << endl;

      return -1;

   }

   // Записываем параметр, указанный при вызове приложения в

   // текстовую строку sUrlAdress. Он должен содержать URL

   // адрес сервера WWW

   CString sUrlAdress;

   sUrlAdress = argv[1];

  

   // Отображаем адрес URL на экране

   cout << "URL address: " << sUrlAdress << endl << endl;

   // Определяем переменные, в которые будут записаны

   // отдельные компоненты адреса, указанного пользователем.

   // Имя сервера

   CString sServer;   

   // Имя объекта на который указывает адрес URL

   CString sObject;

   // Номер порта

   INTERNET_PORT nPort;

   // Тип сервиса или тип протокола

   DWORD dwServiceType;

  

   // Разбираем адрес URL, записанный в строке sUrlAdress

   if (!AfxParseURL(sUrlAdress, dwServiceType, sServer,

                    sObject, nPort))

   {

      // В случае ошибки выводим сообщение и завершаем

      // работу приложения

      cout << "AfxParseURL Error" << endl;

     

      return -1;

   }

   // Проверяем, соответствует ли указанный адрес URL

   // серверу WWW. Для этого тип сервиса должен быть http://



   if(dwServiceType != AFX_INET_SERVICE_HTTP)

   {

         cout << " URL Address not WWW server" << endl;

         return -2;

   }

   // Указатель на объект класса CInternetSession

   CInternetSession* m_InternetSession = NULL;

   // Инициализируем сеанс работы с WinInet - создаем объект

   // класса CInternetSession

   m_InternetSession = new CInternetSession("Connecter");  

   // Запрос для сервера WWW      

   CHttpFile* pFile=NULL;  

   // Определяем указатель на объект класса CFtpConnection

   CHttpConnection*  m_HttpConnection = NULL;

   // Исключения, вызванные в этом блоке try обрабатываются

   // следующим блоком catch

   try

   {

      // Пытаемся соединииться с сервером sServer

      m_HttpConnection =

         m_InternetSession -> GetHttpConnection( sServer );

      // Формируем запрос

      pFile =

         m_HttpConnection -> OpenRequest(

                              CHttpConnection::HTTP_VERB_HEAD,

                              sObject

                             );

      // Дополнительный заголовок запроса HTTP

      CString headerInfo(_T(

         "Accept: text/*\r\nUser-Agent: HTTP Example\r\n"));

  

      // Добавляем к запросу дополнительный заголовок

      if(pFile->AddRequestHeaders(headerInfo))

      {

         // Передаем запрос на сервер

         if(pFile->SendRequest())

         {

            DWORD dwReturnCode;

            // Определяем код завершения запроса

            if(pFile->QueryInfoStatusCode(dwReturnCode))

            {

               // Отображаем код завершения запроса на экране

               CString sMessage;

               sMessage.Format("%d",dwReturnCode);

               cout << "SendRequest: " << sMessage <<

                        endl << endl;

            }

            else

            {

               cout << "Request Error" << endl << endl;



            }

         }

      }

  

   }

   // Обрабатываем исключение CInternetException

   catch (CInternetException* pEx)

   {

      // Временный буфер для сообщения

      TCHAR szErr[1024]; 

      // Выводим сообщение об ошибке

      if (pEx->GetErrorMessage(szErr, 1024))

         cout << "Error: " << szErr <<endl <<endl;

      // Удаляем иссключение

      pEx->Delete();

   }

   // Закрываем запрос

   pFile -> Close();

   // Удаляем объект pFile из памяти

   if(pFile)

      delete pFile;

   // Закрываем соединение с сервером WWW

   m_HttpConnection -> Close();

   // Удаляем объект m_FtpConnection

   delete( m_HttpConnection );

   // Завершаем сеанс связи

   m_InternetSession -> Close();

   // Удаляем объект m_InternetSession

   delete(m_InternetSession);

   return 0;

}

Постройте только что созданный проект и запустите приложение, указав ему в качестве параметра адрес WWW страницы. Адрес должен быть полным - он должен определять метод доступа (в данном случае http://), имя сервера на котором страница расположена и полный путь к файлу страницы WWW.

Приложение соединится с сервером, на котором эта страница расположена и запросит о ней информацию. Результаты запроса будут выведены на экран. На рисунке 3.3 мы показали работу приложения ConsoleHttp, запросив с сервера http://dials.ccas.ru/ страницу с именем frolov.htm.



Рис. 3.2. Приложение ConsoleHttp запрашивает страницы http://www.frolov.ru/~frolov и http://www.glasnet.ru/~frolov


Содержание раздела