Главная страница

программирование. Руководство su P# a n Reference в herbert schildt полное руководство с 0 герберт шилдт


Скачать 3.32 Mb.
НазваниеРуководство su P# a n Reference в herbert schildt полное руководство с 0 герберт шилдт
Анкорпрограммирование
Дата25.01.2022
Размер3.32 Mb.
Формат файлаrtf
Имя файлаc-40-polnoe-rukovodstvo-2011.rtf
ТипРуководство
#341448
страница93 из 97
1   ...   89   90   91   92   93   94   95   96   97








Нажмите клавишу .

Hill,Wright «Group/McGraw‑Hill,McGraw‑Hill Higher Education,McGraw‑Hill/Irwin, McGraw‑Hill/Primis Custom Publishing,McGraw‑Hill/Ryerson,Tata/McGraw‑Hill,

McGraw‑Hill Interamericana,Open University Press, Healthcare Information Group, Platts, McGraw‑Hill Construction, Information & Media Services" />



Нажмите клавишу .    1

Итак, выше приведена часть гипертекстового содержимого, полученного из вебсайта издательства McGraw‑Hill по адресу www.McGraw‑Hill . com. В рассматриваемом здесь примере программы это содержимое просто выводится в исходном виде на экран посимвольно и не форматируется в удобочитаемом виде, как это обычно делается в окне браузера.

Проанализируем данную программу построчно. Прежде всего обратите внимание на использование в ней пространства имен System. Net. Как пояснялось ранее, в этом пространстве имен находятся классы сетевого подключения к Интернету. Обратите также внимание на то, что в данную программу включено пространство имен System. 10, которое требуется для того, чтобы прочитать полученную на веб‑сайте информацию, используя объект типа Stream.

В начале программы создается объект типа WebRequest, содержащий требуемый URL Как видите, для этой цели используется метод Create (), а не конструктор. Это статический член класса WebRequest. Несмотря на то что класс WebRequest является абстрактным, это обстоятельство не мешает вызывать статический метод данного класса. Метод Create () возвращает объект типа HttpWebRequest. Разумеется, его значение требуется привести к типу HttpWebRequest, прежде чем присвоить его переменной req ссылки на объект типа HttpWebRequest. На этом формирование запроса завершается, но его еще нужно отправить по указанному URL

Для того чтобы отправить запрос, в рассматриваемой здесь программе вызывается метод GetResponse () для объекта типа WebRequest. Отправив запрос, метод GetResponse () переходит в состояние ожидания ответа. Как только ответ будет получен, метод GetResponse () возвратит объект типа WebResponse, в котором инкапсулирован ответ. Этот объект присваивается переменной resp. Но в данном случае ответ принимается по протоколу HTTP, и поэтому полученный результат приводится к типу HttpWebResponse. Среди прочего в ответе содержится поток, предназначаемый для чтения данных из источника по указанному URL

Далее поток ввода получается в результате вызова метода GetResponseStream () для объекта resp. Это стандартный объект класса Stream со всеми атрибутами и средствами, необходимыми для организации потока ввода. Ссылка на этот поток присваивается переменной istrm, с помощью которой данные могут быть прочитаны из источника по указанному URI, как из обычного файла.

После этого в программе выполняется чтение данных из веб‑сайта издательства McGraw‑Hill по адресу www .McGraw‑Hill. com и последующий их вывод на экран. А поскольку этих данных много, то они выводятся на экран отдельными порциями по 400 символов, после чего в программе ожидается нажатие клавиши , чтобы продолжить вывод. Благодаря этому выводимые данные можно просматривать без прокрутки экрана. Обратите внимание на то, что данные читаются посимвольно с помощью метода ReadByte () . Напомним, что этот метод возвращает очередной байт из потока ввода в виде значения типа int, которое требуется привести к типу char. По достижении конца потока этот метод возвращает значение ‑ 1.

И наконец, ответный поток закрывается при вызове метода Close () для объекта resp. Вместе с ответным потоком автоматически закрывается и поток ввода. Ответный поток следует закрывать в промежутках между последовательными запросами. В противном случае сетевые ресурсы могут быть исчерпаны, препятствуя очередному подключению к Интернету.

И в заключение анализа рассматриваемого здесь примера следует обратить особое внимание на следующее: для отображения гипертекстового содержимого, получаемого от сервера, совсем не обязательно использовать объект типа HttpWebRequest или HttpWebResponse. Ведь для решения этой задачи в данной программе оказалось достаточно стандартных методов, определенных в классах WebRequest и WebResponse, и не потребовалось прибегать к специальным средствам протокола HTTP. Следовательно, вызовы методов Create () и GetResponse () можно было бы написать следующим образом.

// Сначала создать объект запроса типа WebRequest по указанному URI.

WebRequest req = WebRequest.Create(" http://www.McGraw‑Hill.com ");

// Затем отправить сформированный запрос и получить на него ответ.

WebResponse resp = req.GetResponse() ;

В тех случаях, когда не требуется приведение к конкретному типу реализации протокола, лучше пользоваться классами WebRequest и WebResponse, так как это дает возможность менять протокол, не оказывая никакого влияния на код программы. Но поскольку во всех примерах, приведенных в этой главе, используется протокол HTTP, то в ряде примеров демонстрируются специальные средства этого протокола из классов HttpWebRequest и HttpWebResponse.

Обработка сетевых ошибок

Программа из предыдущего примера составлена верно, но она совсем не защищена от простейших сетевых ошибок, которые способны преждевременно прервать ее выполнение. Конечно, для программы, служащей в качестве примера, это не так важно, как для реальных приложений. Для полноценной обработки сетевых исключений, которые могут быть сгенерированы программой, необходимо организовать контроль вызовов методов Create () , GetResponse ( ) и GetResponseStream ( ). Следует особо подчеркнуть, что генерирование конкретных исключений зависит от используемого протокола. И ниже речь пойдет об ошибках, которые могут возникнуть при использовании протокола HTTP, поскольку средства сетевого подключения к Интернету, доступные в С#, рассматриваются в настоящей главе на примере именно этого протокола.

Исключения, генерируемые методом Create ()

Метод Create (), определенный в классе WebRequest, может генерировать четыре исключения. Так, если протокол, указываемый в префиксе URI, не поддерживается, то генерируется исключение NotSupportedException. Если формат URI оказывается недействительным, то генерируется исключение UriFormatException. А если у пользователя нет соответствующих полномочий для доступа к запрашиваемому сетевому ресурсу, то генерируется исключение System. Security. SecurityException. Кроме того, метод Create () генерирует исключение ArgumentNullException, если он вызывается с пустой ссылкой, хотя этот вид ошибки не имеет непосредственного отношения к сетевому подключению.

Исключения, генерируемые методом GetResponse ()

При вызове метода GetResponse () для получения ответа по протоколу HTTP может произойти целый ряд ошибок. Эти ошибки представлены следующими исключениями: InvalidOperationException, ProtocolViolationException, NotSupportedException и WebException. Наибольший интерес среди них вызывает исключение WebException.

У исключения WebException имеются два свойства, связанных с сетевыми ошибками: Response и Status. С помощью свойства Response можно получить ссылку на объект типа WebResponse в обработчике исключений. Для соединения по протоколу HTTP этот объект описывает характер возникшей ошибки. Свойство Response объявляется следующим образом.

public WebResponse Response { get; }

Когда возникает ошибка, то с помощью свойства Status типа WebException можно выяснить, что именно произошло. Это свойство объявляется следующим образом:

public WebExceptionStatus Status {get; }

где WebExceptionStatus – это перечисление, которое содержит приведенные ниже значения.
CacheEntryNotFound
ConnectFailure
ConnectionClosed
KeepAliveFailure
MessageLengthLimitExceeded
NameResolutionFailure
Pending
PipelineFailure
ProtocolError
ProxyNameResolutionFailure
ReceiveFailure
RequestCanceled
RequestProhibitedByCachePolicy
RequestProhibitedByProxy
SecureChannelFailure
SendFailure
ServerProtocolViolation
Success
Timeout
TrustFailure
UnknownError
Как только будет выяснена причина ошибки, в программе могут быть предприняты соответствующие действия.
Исключения, генерируемые методом GetResponseStream ()

Для соединения по протоколу HTTP метод GetResponseStream () из класса WebResponse может сгенерировать исключение ProtocolViolationException, которое в целом означает, что в работе по указанному протоколу произошла ошибка. Что же касается метода GetResponseStream (), то это означает, что ни один из действительных ответных потоков недоступен. Исключение ObjectDisposedException генерируется в том случае, если ответ уже утилизирован. А исключение IOException, конечно, генерируется при ошибке чтения из потока, в зависимости от того, как организован ввод данных.

Обработка исключений

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

// Пример обработки сетевых исключений.

using System; using System.Net; using System.10;

class NetExcDemo { static void Main() { int ch;

try {

// Сначала создать объект запроса типа 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=l; ; i++) { ch = istrm.ReadByte(); if(ch == ‑1) break;

Console.Write ( (char) ch) ; if((i % 4 0 0)==0) {

Console.Write ("ХпНажмите клавишу .");

Console.ReadLine() ;

}

}

// Закрыть ответный поток. При этом закрывается // также поток ввода istrm. resp.Close ();

} catch(WebException exc) {

Console.WriteLine ("Сетевая ошибка: " + exc.Message +

"\пКод состояния: " + exc.Status);

} catch(ProtocolViolationException exc) {

Console.WriteLine("Протокольная ошибка: " + exc.Message);

} catch(UriFormatException exc) {

Console.WriteLine("Ошибка формата URI: " + exc.Message);

} catch(NotSupportedException exc) {

Console.WriteLine("Неизвестный протокол: " + exc.Message);

} catch(IOException exc) {

Console.WriteLine("Ошибка ввода‑вывода: " + exc.Message);

} catch(System.Security.SecurityException exc) {

Console.WriteLine("Исключение в связи с нарушением безопасности: " + exc.Message);

} catch(InvalidOperationException exc) {

Console.WriteLine("Недопустимая операция: " + exc.Message);

}

}

}

Теперь перехватываются все исключения, которые могут быть сгенерированы сетевыми методами. Так, если изменить вызов метода Create () следующим образом:

WebRequest.Create(" http://www.McGraw‑Hill.com/moonrocket ");

а затем перекомпилировать и еще раз выполнить программу, то в результате может быть выдано приведенное ниже сообщение об ошибке.

Сетевая ошибка: Удаленный сервер возвратил ошибку:    (404)    Не    найден.

Код состояния: ProtocolError

На веб‑сайте по адресу www.McGraw‑Hill . com отсутствует раздел moonrocket, и поэтому он не найден по указанному URI, что и подтверждает приведенный выше результат.

Ради краткости и ясности в программах большинства примеров из этой главы отсутствует полноценная обработка исключений. Но в реальных приложениях она просто необходима.

Класс Uri

Как следует из табл. 26.1, метод WebRequest. Create () существует в двух вариантах. В одном варианте он принимает идентификатор URI в виде строки. Именно этот вариант и был использован в предьтдугцих примерах программ. А во втором варианте этот метод принимает идентификатор URI в виде экземпляра объекта класса Uri, определенного в пространстве имен System. Класс Uri инкапсулирует идентификатор URL Используя класс Uri, можно сформировать URI, чтобы затем передать этот идентификатор методу Create () . Кроме того, идентификатор URI можно разделить на части. Для выполнения многих простых операций в Интернете класс Uri малопригоден. Тем не менее он может оказаться весьма полезным в более сложных ситуациях сетевого подключения к Интернету.

В классе Uri определяется несколько конструкторов. Ниже приведены наиболее часто используемые конструкторы этого класса.

public Uri(string uriString)

public Uri(Uri baseUri, string relativeUri)

В первой форме конструктора объект класса Uri создается по идентификатору URI, заданному в виде строки uriString. А во второй форме конструктора он создается по относительному URI, заданному в виде строки relativeUri относительно абсолютного URI, обозначаемого в виде объекта baseUri типа Uri. Абсолютный URI определяет полный адрес URI, а относительный URI – только путь к искомому ресурсу.

В классе Uri определяются многие поля, свойства и методы, оказывающие помощь в управлении идентификаторами URI или в получении доступа к различным частям URI. Особый интерес представляют приведенные ниже свойства.
Свойство
Описание
public
string Host { get; }
Получает имя сервера
public
string LocalPath { get; }
Получает локальный путь к файлу
public
string. PathAndQuery { get; }
Получает абсолютный путь и строку запроса
public
int Port { get; }
Получает номер порта для указанного протокола. Так, для протокола HTTP номер порта равен 80
public
string Query { get; }
Получает строку запроса
public
string Scheme { get; }
Получает протокол
Перечисленные выше свойства полезны для разделения URI на составные части. Применение этих свойств демонстрируется в приведенном ниже примере программы.

// Пример применения свойств из класса Uri.

using System; using System.Net;

class UriDemo {

static void Main() {

Uri sample = new Uri(" http://HerbSchildt.com/somefile.txt?SomeQuery ");

Console.WriteLine("Хост: " + sample.Host);

Console.WriteLine("Порт: " + sample.Port);

Console.WriteLine("Протокол: " + sample.Scheme);

Console .WriteLine ("Локальный путь: 11 + sample. LocalPath) ;

Console.WriteLine("Запрос: " + sample.Query);

Console.WriteLine("Путь и запрос: " + sample.PathAndQuery);

}

}

Эта программа дает следующий результат.

Хост: HerbSchildt.com Порт: 80 Протокол: http

Локальный путь: /somefile.txt Запрос: ?SomeQuery

Путь и запрос: /somefile.txt?SomeQuery

Доступ к дополнительной информации, получаемой в ответ по протоколу HTTP

С помощью сетевых средств, имеющихся в классе HttpWebResponse, можно получить доступ к другой информации, помимо содержимого указываемого ресурса. К этой информации, в частности, относится время последней модификации ресурса, а также имя сервера. Она оказывается доступной с помощью различных свойств, связанных с получаемым ответом. Все эти свойства, включая и те что, определены в классе WebResponse, сведены в табл. 26.5. В приведенных далее примерах программ демонстрируется применение этих свойств на практике.
Свойство
Описание
1   ...   89   90   91   92   93   94   95   96   97


написать администратору сайта