кфайлу — путь к конкретному файлу. Если же Путьк
файлу не указан, то получается страница, доступная на указанном сервере по умолча
нию. И наконец, Запрос обозначает информацию, отправляемую на сервер. Указывать
Запрос необязательно. В C# идентификаторы URI инкапсулированы в класс Uri, рас
сматриваемый далее в этой главе.
Основы организации доступа к Интернету
В классах, находящихся в пространстве имен System.Net, поддерживается модель
взаимодействия с Интернетом по принципу запроса и ответа. При таком подходе
пользовательская программа, являющаяся клиентом, запрашивает информацию у
сервера, а затем переходит в состояние ожидания ответа. Например, в качестве запроса
программа может отправить на сервер идентификатор URI некоторого веб-сайта. В от
вет она получит гипертекстовую страницу, соответствующую указанному идентифи
катору URI. Такой принцип запроса и ответа удобен и прост в применении, поскольку
большинство деталей сетевого взаимодействия реализуются автоматически.
На вершине иерархии сетевых классов находятся классы WebRequest и
WebResponse, реализующие так называемые подключаемые протоколы. Как должно
быть известно большинству читателей, для передачи данных в сети применяется не
сколько разнотипных протоколов. К числу наиболее распространенных в Интернете
относятся протокол передачи гипертекстовых файлов (HTTP), а также протокол пере
дачи файлов (FTP). При создании идентификатора URI его префикс обозначает приме
няемый сетевой протокол. Например, в идентификаторе http://www.HerbSchildt.
com используется префикс http, обозначающий протокол передачи гипертекстовых
файлов (HTTP).
Как упоминалось выше, классы WebRequest и WebResponse являются абстракт
ными, а следовательно, в них определенны в самом общем виде операции запроса и
ответа, типичные для всех протоколов. От этих классов наследуют более конкретные
производные классы, в которых реализуются отдельные протоколы. Эти производные
классы регистрируются самостоятельно, используя для этой цели статический метод
RegisterPrefix(), определенный в классе WebRequest. При создании объекта типа
WebRequest автоматически используется протокол, указываемый в префиксе URI,
если, конечно, он доступен. Преимущество такого принципа "подключения" протоко
лов заключается в том, что большая часть кода пользовательской программы остается
без изменения независимо от типа применяемого протокола.
В среде выполнения .NET Runtime протоколы HTTP, HTTPS и FTP определяются ав
томатически. Так, если указать идентификатор URI с префиксом HTTP, то будет авто
матически получен HTTP-совместимый класс, который поддерживает протокол HTTP.
А если указать идентификатор URI с префиксом FTP, то будет автоматически получен
FTP-совместимый класс, поддерживающий протокол FTP.
При сетевом подключении к Интернету чаще всего применяется протокол HTTP,
поэтому именно он и рассматривается главным образом в этой главе. (Тем не менее
аналогичные приемы распространяются и на все остальные поддерживаемые протоко
лы.) Протокол HTTP поддерживается в классах HttpWebRequest и HttpWebResponse.
Эти классы наследуют от классов WebRequest и WebResponse, а кроме того, име
ют собственные дополнительные члены, применимые непосредственно к протоколу
HTTP.
В пространстве имен System.Net поддерживается как синхронная, так и асинхрон
ная передача данных. В Интернете предпочтение чаще всего отдается синхронным
транзакциям, поскольку ими легче пользоваться. При синхронной передаче данных
пользовательская программа посылает запрос и затем ожидает ответа от сервера. Но
для некоторых разновидностей высокопроизводительных приложений более подхо
дящей оказывается асинхронная передача данных. При таком способе передачи дан
ных пользовательская программа продолжает обработку данных, ожидая ответа на
переданный запрос. Но организовать асинхронную передачу данных труднее. Кроме
того, не во всех программах можно извлечь выгоды из асинхронной передачи данных.
Например, когда требуется получить информацию из Интернета, то зачастую ниче
го другого не остается, как ожидать ее. В подобных случаях потенциал асинхронной
передачи данных используется не полностью. Вследствие того что синхронный доступ
к Интернету реализуется проще и намного чаще, именно он и будет рассматриваться
в этой главе.
Далее речь пойдет прежде всего о классах WebRequest и WebResponse, поскольку
именно они положены в основу сетевых программных средств, доступных в простран
стве имен System.Net.
Класс WebRequest
Класс WebRequest управляет сетевым запросом. Он является абстрактным, по
скольку в нем не реализуется конкретный протокол. Тем не менее в нем определяются
те методы и свойства, которые являются общими для всех сетевых запросов. В табл. 26.1
сведены методы, определенные в классе WebRequest и поддерживающие синхронную
передачу данных, а в табл. 26.2 — свойства, объявляемые в классе WebRequest. Уста
навливаемые по умолчанию значения свойств задаются в производных классах. Откры
тые конструкторы в классе WebRequest не определены.
Для того чтобы отправить запрос по адресу URI, необходимо сначала создать
объект класса, производного от класса WebRequest и реализующего требуемый про
токол. С этой целью вызывается статический метод Create(), определенный в клас
се WebRequest. Метод Create() возвращает объект класса, наследующего от класса
WebRequest и реализующего конкретный протокол.
Таблица 26.1. Методы, определенные в классе WebRequest
Метод Описание
public static WebRequest
Create(string
requestUriString)
Создает объект типа WebRequest для иден
тификатора URI, указываемого в строке
requestUriString. Возвращаемый объект
реализует протокол, заданный префиксом иден
тификатора URI. Следовательно, возвращаемый
объект будет экземпляром класса, производного
от класса WebRequest. Если затребованный про
токол недоступен, то генерируется исключение
NotSupportedException. А если недействите
лен указанный формат идентификатора URI, то ге
нерируется исключение UriFormatException
Окончание табл. 26.1
Таблица 26.2. Свойства, определенные в классе WebRequest
Метод Описание
public static WebRequest
Create(Uri requestUri)
Создает объект типа WebRequest для иденти
фикатора URI, указываемого с помощью пара
метра requestUri. Возвращаемый объект
реализует протокол, заданный префиксом иден
тификатора URI. Следовательно, возвращаемый
объект будет экземпляром класса, производного
от класса WebRequest. Если затребованный про
токол недоступен, то генерируется исключение
NotSupportedException
public virtual Stream
GetRequestStream()
Возвращает поток вывода, связанный с запрошен
ным ранее идентификатором URI
public virtual WebResponse
GetResponse()
Отправляет предварительно сформированный за
прос и ожидает ответа. Получив ответ, возвращает
его в виде объекта класса WebReponse. Этот объ
ект используется затем в программе для получения
информации по указанному адресу URI
Свойство Описание
public AuthenticationLevel
AuthenticationLevel{ get; set; }
Получает или устанавливает уровень аутентифи
кации
public virtual
RequestCachePolicy CachePolicy
{ get; set; }
Получает или устанавливает правила использо
вания кеша, определяющие момент получения
ответа из кеша
public virtual string
ConnectionGroupName { get;
set; }
Получает или устанавливает имя группы подклю
чения. Группы подключения представляют собой
способ создания ряда запросов. Они не нужны
для простых транзакций в Интернете
public virtual long
ContentLength { get; set; }
Получает или устанавливает длину передаваемо
го содержимого
public virtual string
ContentType { get; set; }
Получает или устанавливает описание переда
ваемого содержимого
public virtual Icredentials
Credentials { get; set; }
Получает или устанавливает мандат, т.е. учетные
данные пользователя
public static
RequestCachePolicy
DefaultCachePolicy { get; set; }
Получает или устанавливает правила использо
вания кеша по умолчанию, определяющие мо
мент получения ответа из кеша
public static IWebProxy
DefaultWebProxy { get; set; }
Получает или устанавливает используемый по
умолчанию прокси-сервер
public virtual
WebHeaderCollection Headers{
get; set; }
Получает или устанавливает коллегию заголовков
public TokenImpersonationLevel
ImpersonationLevel { get; set; }
Получает или устанавливает уровень анонимно
го воплощения
Класс WebResponse
В классе WebResponse инкапсулируется ответ, получаемый по запросу. Этот класс
является абстрактным. В наследующих от него классах создаются отдельные его вер
сии, поддерживающие конкретный протокол. Объект класса WebResponse обыч
но получается в результате вызова метода GetResponse(), определенного в классе
WebRequest. Этот объект будет экземпляром отдельного класса, производного от
класса WebResponse и реализующего конкретный протокол. Методы, определенные
в классе WebResponse, сведены в табл. 26.3, а свойства, объявляемые в этом классе, —
в табл. 26.4. Значения этих свойств устанавливаются на основании каждого запроса в
отдельности. Открытые конструкторы в классе WebResponse не определяются.
Таблица 26.3. Наиболее часто используемые методы, определенные в классе WebResponse
Метод Описание
public virtual void Close() Закрывает ответный поток. Закрывает также
поток ввода ответа, возвращаемый методом
GetResponseStream()
public virtual Stream
GetResponseStream()
Возвращает поток ввода, связанный с запрашивае
мым URI. Из этого потока могут быть введены дан
ные из запрашиваемого URI
Окончание табл. 26.2
Свойство Описание
public virtual string Method {
get; set; }
Получает или устанавливает протокол
public virtual bool
PreAuthenticate { get; set; }
Если принимает логическое значение true, то в
отправляемый запрос включается информация
для аутентификации. А если принимает логиче
ское значение false, то информация для аутен
тификации предоставляется только по требова
нию адресата URI
public virtual IWebProxy Proxy
{ get; set; }
Получает или устанавливает прокси-сервер. При
менимо только в тех средах, где используется
прокси-сервер
public virtual Uri RequestUri
{ get; }
Получает идентификатор URI конкретного запроса
public virtual int Timeout {
get; set; }
Получает или устанавливает количество милли
секунд, в течение которых будет ожидаться ответ
на запрос. Для установки бесконечного ожида
ния используется значение Timeout.Infinite
public virtual bool
UseDefaultCredential { get;
set; }
Получает или устанавливает значение, которое
определяет, используется ли для аутентификации
устанавливаемый по умолчанию мандат. Если
имеет логическое значение true, то использу
ется устанавливаемый по умолчанию мандат,
т.е. учетные данные пользователя, в противном
случае этот мандат не используется
Классы HttpWebRequest и HttpWebResponse
Оба класса, HttpWebRequest и HttpWebResponse, наследуют от классов
WebRequest и WebResponse и реализуют протокол HTTP. В ходе этого процесса
в обоих классах вводится ряд дополнительных свойств, предоставляющих подробные
сведения о транзакции по протоколу HTTP. О некоторых из этих свойств речь пойдет
далее в настоящей главе. Но для выполнения простых операций в Интернете эти до
полнительные свойства, как правило, не требуются.
Первый простой пример
Доступ к Интернету организуется на основе классов WebRequest и WebResponse.
Поэтому, прежде чем рассматривать этот процесс более подробно, было бы полезно
обратиться к простому примеру, демонстрирующему порядок доступа к Интернету
по принципу запроса и ответа. Глядя на то, как эти классы применяются на практике,
легче понять, почему они организованы именно так, а не как-то иначе.
В приведенном ниже примере программы демонстрируется простая, но весьма
типичная для Интернета операция получения гипертекстового содержимого из кон
кретного веб-сайта. В данном случае содержимое получается из веб-сайта издатель
ства McGraw-Hill по адресу www.McGraw-Hill.com, но вместо него можно подставить
адрес любого другого веб-сайта. В этой программе гипертекстовое содержимое выво
дится на экран монитора отдельными порциями по 400 символов, чтобы полученную
информацию можно было просматривать, не прибегая к прокрутке экрана.
// Пример доступа к веб-сайту.
using System;
Таблица 26.4. Свойства, определенные в классе WebResponse
Свойство Описание
public virtual long
ContentLength { get; set; }
Получает или устанавливает длину принимаемого со
держимого. Устанавливается равным -1, если дан
ные о длине содержимого недоступны
public virtual string
ContentType { get; set; }
Получает или устанавливает описание принимаемого
содержимого
public virtual
WebHeaderCollection Headers
{ get; }
Получает или устанавливает коллекцию заголовков,
связанных с URI
public virtual bool
IsFromCache { get; }
Принимает логическое значение true, если запрос
получен из кэша. А если запрос доставлен по сети, то
принимает логическое значение false
public virtual bool
IsMutuallyAuthenticated {
get; }
Принимает логическое значение true, если клиент
и сервер опознают друг друга, а иначе — принимает
логическое значение false
public virtual Uri
ResponseUri { get; }
Получает URI, по которому был сформирован ответ.
Этот идентификатор может отличаться от запрашивае
мого, если ответ был переадресован по другому URI
using System.Net;
using System.IO;
class NetDemo {
static void Main() {
int ch;
// Сначала создать объект запроса типа WebRequest по указанному URI.
HttpWebRequest req = (HttpWebRequest)
WebRequest.Create("http://www.McGraw-Hill.com");
// Затем отправить сформированный запрос и получить на него ответ.
HttpWebResponse resp = (HttpWebResponse)
req.GetResponse();
// Получить из ответа поток ввода.
Stream istrm = resp.GetResponseStream();
/ А теперь прочитать и отобразить гипертекстовое содержимое,
полученное по указанному URI. Это содержимое выводится на экран
отдельными порциями по 400 символов. После каждой такой порции
следует нажать клавишу , чтобы вывести на экран
следующую порцию из 400 символов. /
for(int i=1; ; i++) {
ch = istrm.ReadByte ();
if(ch == -1) break;
Console.Write((char) ch);
if((i%400)==0) {
Console.Write("\nНажмите клавишу .");
Console.ReadLine();
}
}
// Закрыть ответный поток. При этом закрывается также поток ввода istrm.
resp.Close();
}
}
Ниже приведена первая часть получаемого результата. (Разумеется, это содержи
мое может со временем измениться в связи с обновлением запрашиваемого веб-сайта,
и поэтому у вас оно может оказаться несколько иным.)