Главная страница
Навигация по странице:

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

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

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

  • Свойство

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

  • Использование Свойства LastModified

  • Учебный проект: программа MiniCrawler

  • Использование класса WebClient

  • Метод

  • Часть III Применение языка C

  • Справочник по C# Герберт Шилдт ббк 32. 973. 26018 75 Ш57 удк 681 07 Издательский дом "Вильямс" Зав редакцией


    Скачать 5.05 Mb.
    НазваниеСправочник по C# Герберт Шилдт ббк 32. 973. 26018 75 Ш57 удк 681 07 Издательский дом "Вильямс" Зав редакцией
    АнкорC #.pdf
    Дата08.12.2017
    Размер5.05 Mb.
    Формат файлаpdf
    Имя файлаC #.pdf
    ТипСправочник
    #10795
    страница45 из 52
    1   ...   41   42   43   44   45   46   47   48   ...   52


    Find all the right computer books and learning tools at <br>Osborne McGraw-Hill/TITLE> <br></div> <div> <br><i><b>652</b></i> <br>Часть II. Библиотека C# learning tools at Osborne McGraw-Hill"> it books, computer books, database books, programming <br>Нажмите клавишу. books, networking books, certification books, computing books, computer application books, hardware books, information technology books, operating systems, web development, oracle press, communications, complete reference, how to do everything, yellow pages, book publisher, certification study guide, reference book, security, network security, ebusiness, e-business, a+, network+, i-net+, cisco ce <br>Нажмите клавишу. <br>Поскольку программа лишь <a href="/otchet-po-laboratornoj-rabote-1-atmel-ch-1-voronin-d-a-gruppa/index.html" title="Отчет по лабораторной работе №1 Atmel ч. 1 Воронин Д. А. Группа 16-эпв Проверил: Слядзевская К. П">посимвольно отображает принятое содержимое</a>, она, в отличие от браузера, не форматирует его. <br>Каждая строка этой программы заслуживает рассмотрения. Прежде всего обратите внимание на использование пространства имен <br>System.Net<br>. Как упоминалось выше, именно это пространство имен содержит классы, обеспечивающие сетевые возможности <br>C#. Здесь также используется пространство имен <br>System.IO<br>. Его присутствие обусловлено использованием объекта класса stream<br>, который позволяет считывать информацию с Web-сайта. <br>Программа начинается с создания <br>WebRequest<br>-объекта, который содержит нужный <br>URI-адрес. Обратите внимание на то, что для этого используется метод <br>Create()<br>, а не конструктор. Метод <br>Create()<br> — статический член класса <br>WebRequest<br>. Несмотря на то что класс <br>WebRequest<br> — абстрактный, мы имеем возможность вызывать его статические методы. Метод <br>Create()<br> возвращает <br>WebRequest<br>-объект, который содержит протокол, <br>“настраиваемый” на основе префикса URI-адреса. В данном случае используется протокол <br>HTTP. Поэтому метод <br>Create()<br> возвращает <br>HttpWebRequest<br>-объект. Если значение, возвращаемое методом <br>Create()<br>, присваивается <br>HttpWebRequest<br>-ссылке с именем req<br>, то оно обязательно должно быть приведено (в явной форме) к типу <br>HttpWebRequest<br>. После выполнения этой инструкции наш запрос создан, но еще не отправлен по заданному URI-адресу. <br>Чтобы отослать запрос, программа вызывает метод <br>GetResponse()<br> для объекта класса <br>WebRequest<br>. После отправки запроса метод <br>GetResponse()<br> ожидает ответа. По получении ответа метод <br>GetResponse()<br> возвращает <br>WebResponse<br>-объект, который инкапсулирует принятый ответ. Этот объект присваивается ссылке resp<br>. Так как в данном случае в ответе используется протокол HTTP, результат вызова метода <br>GetResponse() приводится к типу <br>HttpWebResponse<br>. Ответ содержит поток, который можно использовать для считывания данных с Web-сайта с заданным URI-адресом. <br>Затем посредством вызова метода <br>GetResponseStream() для объекта resp считывается входной поток, который представляет собой стандартный объект класса <br>Stream<br>, имеющий все атрибуты любого другого входного потока. Ссылка на этот поток присваивается переменной istrm<br>. Используя переменную istrm<br>, данные, расположенные по заданному URI-адресу, можно прочитать так же, как считываются данные из файла. <br>Считанные данные программа отображает на экране. Поскольку объем данных может быть довольно большим, процесс отображения приостанавливается после вывода каждых <br>400 символов, и программа переходит в режим ожидания, который прервется <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>653</b></i> нажатием клавиши <Enter>. Поэтому вы можете до бесконечности изучать первую порцию отображенной на экране информации. Обратите внимание на то, что символы считываются с помощью метода <br>ReadByte()<br>. Вспомните, что этот метод возвращает следующий символ из входного потока в виде int<br>-значения, которое должно быть приведено к типу char<br>. При достижении конца потока метод возвращает число — 1. <br>Наконец, поток, содержащий ответ, закрывается посредством вызова метода <br>Close()<br> для объекта resp<br>. При закрытии потока с ответом автоматически закрывается и входной поток. Важно закрывать поток, содержащий ответ, между запросами. В противном случае могут исчерпаться сетевые ресурсы, и следующее подключение к Internet может не состояться. <br>Здесь важно отметить еще одну деталь. Для отображения гипертекстовой информации с Web-сайта <br>Osborne.com необязательно использовать объект класса <br>HttpWebRequest или <br>HttpWebResponse<br>. Поскольку в предыдущей программе не использовались никакие специфические HTTP-средства, для решения этой задачи было бы вполне достаточно стандартных методов, определенных в классах <br>WebRequest и <br>WebResponse<br>. Поэтому вызовы методов <br>Create()<br> и <br>GetResponse() можно переписать так: <br>// Сначала создаем WebRequest-запрос по URI-адресу. <br>WebRequest req = WebRequest.Create( <br>"http://www.osborne.com"); <br>// Затем отправляем запрос и получаем ответ. <br>WebResponse resp = req.GetResponse(); <br>Разработчики из компании Microsoft считают, что в случаях, когда необязательно использовать операцию приведения к типу реализации конкретного протокола, лучше обходиться средствами, предоставляемыми классами <br>WebRequest и <br>WebResponse<br>. Это позволяет изменять протоколы, не внося изменений в программы. Но поскольку во всех примерах этой главы используется протокол HTTP (а в некоторых из них и специфические <br>HTTP-средства), то в приведенных здесь программах задействованы классы <br>HttpWebRequest<br> И <br>HttpWebResponse<br><b><span id='Обработка_сетевых_ошибок'>Обработка сетевых ошибок </span></b><br>Несмотря на то что программа, приведенная в предыдущем разделе, вполне корректна, она совершенно беззащитна перед потенциальными “ударами судьбы”, которые могут внезапно оборвать ее “жизнь”. В реальных приложениях необходимо предусмотреть все возможные неприятности и обеспечить полную обработку сетевых исключений, которые может сгенерировать программа. Для этого нужно проконтролировать обращения к методам <br>Create()<br>, <br>GetResponse()<br> и <br>GetResponseStream()<br>. Все типы потенциальных ошибок рассматриваются в следующих разделах. <br><b><span id='Исключения,_генерируемые_методом_Create()'>Исключения, генерируемые методом Create() </span></b><br>Метод <br>Create()<br>, определенный в классе <br>WebRequest<br>, может сгенерировать три исключения. Если протокол, заданный URI-префиксом, не поддерживается, генерируется исключение типа <br>NotSupportedException<br>. Если неверно задан формат URI- идентификатора, генерируется исключение типа <br>UriFormatException<br>. Метод <br>Create()<br>, вызванный с использованием нулевой ссылки, может сгенерировать также исключение типа <br>ArgumentNullException<br>, хотя эта ошибка не относится к тем, которые генерируются сетевыми средствами. <br></div> <div> <br><i><b>654</b></i> <br>Часть II. Библиотека C# <br>Исключения, генерируемые методом <br>GetResponse() <br>Если ошибка обнаружится в процессе получения ответа, т.е. при вызове метода <br>GetResponse()<br>, генерируется исключение типа <br>WebException<br>. Помимо членов, определенных для всех исключений, в классе <br>WebException определены также два дополнительных свойства, которые связаны с сетевыми ошибками: <br>Response и <br>Status<br>Внутри обработчика исключения с помощью свойства <br>Response можно получить ссылку на объект класса <br>WebResponse<br>. Этот объект будет возвращен методом <br>GetResponse()<br>, если исключение не генерируется. Определение свойства <br>Response выглядит так: public WebResponse Response { get; } <br>Если ошибка все-таки возникла, то чтобы понять, что именно произошло, можно использовать свойство status<br>. Его определение имеет следующий вид: public WebExceptionStatus Status { get; } <br>WebExceptionStatus<br> — это перечисление, которое содержит следующие значения: <br>ConnectFailure ConnectionClosed <br>KeepAliveFailure <br>NameResolutionFailure Pending <br>PipelineFailure <br>ProtocolError ProxyNameResolutionFailure <br>ReceiveFailure <br>RequestCanceled SecureChannelFailure <br>SendFailure <br>ServerProtocolViolation Success <br>Timeout <br>TrustFailure <br>После выяснения причины ошибки программа может предпринять соответствующие действия. <br><b><span id='Исключения,_генерируемые_методом_GetResponseStream()'>Исключения, генерируемые методом GetResponseStream() </span></b><br>Метод <br>GetResponseStream() класса <br>GetResponse может генерировать исключение типа <br>ProtocolViolationException<br>, которое в общем случае означает, что произошла ошибка, связанная с протоколом. А поскольку ее возникновение имеет отношение к методу <br>GetResponseStream()<br>, значит нет ни одного потока, содержащего ответную информацию. В процессе чтения потока может также быть сгенерировано исключение типа <br>IOException<br><b>Обработка исключений </b><br>В следующую программу, которая основана на предыдущем примере, добавлены обработчики всех возможных сетевых исключений: <br>// Обработка сетевых исключений. using System; using System.Net; using System.IO; class NetExcDemo { public static void Main() { int ch; try <br>{ <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>655</b></i> <br> // <br>Сначала создаем WebRequest-запрос по URI-адресу. <br> HttpWebRequest req = (HttpWebRequest) <br> WebRequest.Create("http://www.osborne.com"); <br> // <br>Затем отправляем запрос и получаем ответ. <br> HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); <br> //Из ответа получаем входной поток. <br> Stream istrm = resp.GetResponseStream(); <br> /* <br>А теперь считываем и отображаем html-документ, полученный от заданного URI. Текст "не улетит" с экрана, поскольку данные отображаются порциями объемом в 400 символов. Просмотрев очередные <br> 400 символов, нажмите клавишу <ENTER> для получения следующей часть документа. */ for(int i=1;; i++) { ch <br>= istrm.ReadByte(); if(ch == -1) break; <br> Console.Write((char) ch); if((i%400)==0) <br>{ <br> Console.Write("\nНажмите клавишу."); <br> Console.Read(); <br> } <br> } <br> // <br>Закрываем поток, содержащий ответ. При этом <br> // автоматически закроется и входной поток istrm. resp.Close(); <br> } catch(WebException exc) { <br> Console.WriteLine("Сетевая ошибка: " + exc.Message + <br> "\nКод состояния: " + exc.Status); <br> } catch(ProtocolViolationException exc) { <br> Console.WriteLine("Ошибка протокола: " + exc.Message); <br> } catch(UriFormatException exc) { <br> Console.WriteLine("Ошибка формата URI: " + exc.Message); <br> } catch(NotSupportedException exc) { <br> Console.WriteLine("Неизвестный протокол: " + exc.Message); <br> } catch(IOException exc) { <br> Console.WriteLine("I/O Error: " + exc.Message); <br> } <br> } <br>} <br>В этом варианте программы будут перехвачены исключения, потенциально генерируемые Internet-методами. Например, если используемое в программе обращение к методу <br>Create()<br> заменить следующим <br>WebRequest.Create("http://www.osborne.com/moonrocket"); и перекомпилировать программу, а затем ее выполнить, вы непременно получите такое сообщение: <br>Сетевая ошибка: The remote server returned an error: (404) Not <br>Found. Код состояния: ProtocolError <br></div> <div> <br><i><b>656</b></i> <br>Часть II. Библиотека C# <br>Поскольку Web-сайт <br>Osborne.com не имеет каталога с именем “moonrocket”, вполне естественно, что этот URI-адрес не обнаружен. <br>Чтобы не загромождать примеры, большинство программ из этой главы не содержит полной обработки исключений. Но вы должны понимать, что в реальные приложения ее необходимо включать в полном объеме. <br><b>Класс </b><br><b>URI</b><br>Возможно, вы обратили внимание на то, что в табл. 23.1 метод <br>WebRequest.Create()<br> представлен в двух различных версиях. Одна из них принимает <br>URI в виде строки, и именно эта версия используется в предыдущих программах. Вторая принимает URI как экземпляр класса <br>Uri<br>. Класс <br>Uri инкапсулирует URI-идентификатор. <br>Используя класс <br>Uri<br>, можно создать такой URI-адрес, который будет принят второй версией метода <br>Create()<br>. При этом можно разбить URI-идентификатор на части. И хотя в случае простых Internet-операций можно обойтись без класса <br>Uri<br>, все же в более сложных случаях он окажется ценным подспорьем. <br>В классе <br>Uri определено несколько конструкторов. Два наиболее употребимые из них определяются так: public Uri(string <br><i>uri</i><br>) public Uri(string <br><i>base</i><br>, string <br><i>rel</i><br>) <br>Первая форма позволяет создать <br>Uri<br>-объект на основе URI-адреса, заданного в виде строки. Вторая служит для создания <br>Uri<br>-объекта путем сложения относительного URI- идентификатора, заданного параметром <br><i>rel</i><br><i>, </i>с базовым URI-идентификатором, заданным параметром <br><i>base</i><br><i>. </i>Базовый URI-идентификатор определяет сам URI-адрес, а относительный — только сетевой маршрут. <br>В классе <br>Uri определено множество полей, <a href="/lekcii-po-kursu-soprotivlenie-materialov/index.html" title="Лекции по курсу «сопротивление материалов»">свойств и методов</a>, которые позволяют управлять URI-идентификаторами или предоставляют доступ к различным его частям. <br>Чаще всего используются следующие свойства. <br><i><b><span id='Свойство'>Свойство </span></b></i><br><i><b>Описание </b></i><br>public string Host <br>{ get; } <br>Получает имя сервера public string LocalPath <br>{ get; } <br>Получает маршрут, определяющий местоположение файла public string PathAndQuery <br>{ get; } <br>Получает маршрут и строку запроса public int Port <br>{ get; } <br>Получает номер порта для заданного протокола Для HTTP номер порта равен 30 public string Query <br>{ get; } <br>Получает строку запроса public string Scheme <br>{ get; } <br>Получает протокол <br>Эти свойства полезно применять при разбиении URI-идентификатора на составные части. Их использование демонстрирует следующая программа: <br>// Использование класса Uri. using System; using System.Net; <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>657</b></i> class UriDemo { public static void Main() { <br> Uri sample = new Uri( <br> "http://MySite.com/soraefile.txt?SomeQuery"); <br> Console.WriteLine("Хост: " + sample.Host); <br> Console.WriteLine("Порт: " + sample.Port); <br> Console.WriteLine("Протокол: " + sample.Scheme); <br> Console.WriteLine("Локальный маршрут: " + sample.LocalPath); <br> Console.WriteLine("Запрос: " + sample.Query); <br> Console.WriteLine("Маршрут и запрос: " + sample.PathAndQuery); <br> } <br>} <br>Вот результаты выполнения программы: <br>Хост: mysite.com <br>Порт: 80 <br>Протокол: http <br>Локальный маршрут: /somefile.txt <br>Запрос: ?SomeQuery <br>Маршрут и запрос: /somefile.txt?SomeQuery <br><b><span id='Доступ_к_дополнительной_HTTP-информации'>Доступ к дополнительной HTTP-информации </span></b><br>Используя класс <br>HttpWebResponse<br>, можно получить доступ не только к содержимому заданного ресурса, но и к информации, которая включает, например, время последней URI-модификации и имя сервера. Эту информацию можно получить с помощью различных свойств, перечисленных в табл. 23.5 (четыре из них определены в классе <br>WebResponse<br>). Об их использовании и пойдет речь в следующих разделах. <br>Таблица 23.5. Свойства, определенные в классе HttpWebResponse <br><i><b>Свойство </b></i><br><i><b>Описание </b></i><br>Public string CharacterSet <br>{ get; } <br>Получает название используемого символьного набора <br>Public string ContentEncoding <br>{ get; } <br>Получает название схемы кодирования. <br>Public long ContentLength <br>{ get; } <br>Получает длину принимаемого содержимого. Если она недоступна, свойство содержит -1 <br>Public string ContentType <br>{ get; } <br>Получает описание содержимого <br>Public CookieCollection Cookies <br>{ get; set; } <br>Получает или устанавливает список cookie-данных, присоединенных к ответу <br>Public WebHeaderCollection <br>Headers{ get; } <br>Получает коллекцию заголовков, присоединенных к ответу <br>Public DateTime LastModified <br>{ get; } <br>Получает время последней URI-модификации <br>Public string Method { get; } <br>Получает строку, которая задает способ ответа <br></div> <div> <br><i><b>658</b></i> <br>Часть II. Библиотека C# <br>Окончание табл. 23.5 <br><i><b>Свойство </b></i><br><i><b>Описание </b></i><br>public Version <br>Получает объект класса <br>Version<br>, который описывает версию <br>ProtocolVersion { get; } протокола HTTP, используемую в транзакции public uri ReponseUri { get; } <br>Получает URI-идентификатор, по которому сгенерирован ответ. Он может отличаться от запрошенного, если ответ был перенаправлен по другому URI-адресу public string Server { get; } <br>Получает строку, которая представляет имя сервера public HttpStatusCode <br>StatusCode { get; } <br>Получает объект класса <br>HttpStatusCode<br>, который описывает состояние транзакции public string StatusDescription <br>{ get; } <br>Получает строку, которая представляет состояние транзакции в форме, удобной для восприятия человеком <br><b>Доступ к заголовку </b><br>С помощью свойства Headers, которое определено в классе <br>HttpWebResponse<br>, можно получить доступ к заголовочной информации HTTP-ответа: public WebHeaderCollection Headers{ get; } <br>HTTP-заголовок состоит из пар имя/значение, представленных в виде строк. Каждая такая пара хранится в объекте класса <br>WebHeaderCollection<br>. Это — специализированная коллекция, предназначенная для хранения пар ключ/значение, которую можно использовать подобно любой другой коллекции (см. главу 22). Строковый массив имен можно получить из свойства <br>AllKeys<br>. Значение, связанное с конкретным именем, можно получить с помощью индексатора. Индексатор здесь перегружен на прием либо числового индекса, либо имени. <br>В следующей программе отображаются все заголовки, относящиеся к Web-сайту <br>Osborne.com<br>: <br>// Отображение заголовков Web-сайта. using System; using System.Net; class HeaderDemo { public static void Main() { <br> // <br>Создаем WebRequest-запрос по URI-адресу. <br> HttpWebRequest req = (HttpWebRequest) <br> WebRequest.Create("http://www.osborne.com"); <br> // <br>Отправляем этот запрос и получаем ответ. <br> HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); <br> // <br>Получаем список имен. string[] names = resp.Headers.AllKeys; <br> // <br>Отображаем заголовок в виде пар имя/значение. <br> Console.WriteLine("{0,-20}{1}\n", <br>"Имя", "Значение"); foreach(string n in names) <br> Console.WriteLine("{0,-20}{1]", n, resp.Headers[n]); <br> // <br>Закрываем поток, содержащий ответ. <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>659</b></i> resp.Close(); <br> } <br>} <br>Вот какие были получены результаты (не забывайте, что заголовочная информация <br>Web-сайта <br>Osbome.com со временем может измениться, поэтому результаты, полуденные вами, могут несколько отличаться): <br>Имя Значение <br>Date Mon, 14 Jan 2002 17:45:50 GMT <br>Server Apache/1.3.9 (Unix) PHP/3.0.14 <br>Keep-Alive timeout=30, max=500 <br>Connection Keep-Alive <br>Transfer-Encoding chunked <br>Content-Type text/html <br><b>Доступ к cookie-данным </b><br>Доступ к cookie-данным, связанным с HTTP-ответом, можно получить с помощью свойства <br>Cookies<br>, которое определено в классе <br>HttpWebResponse<br>. Cookie-данные, которые хранятся браузером, состоят из пар имя/значение. Они способны упростить определенные типы операций Web-доступа. Вот как выглядит определение свойства <br>Cookies<br>: public CookieCollection Cookies { get; set; } <br>Класс <br>CookieCollection реализует интерфейсы <br>ICollection и <br>IEnumerable<br>, и его можно использовать подобно любой другой коллекции (см. главу 22). <br>Он <a href="/referat-po-otechestvennoj-istorii-rossijskij-flot-pri-petre-i/index.html" title="Реферат по отечественной истории Российский флот при Петре i тузлуков А. И. студент группы ам 161 (2)">имеет индексатор</a>, который позволяет получить cookie-данные по заданному индексу или его имени. <br>Коллекция типа <br>CookieCollection предназначена для хранения объектов типа <br>Cookie<br>. В классе <br>Cookie определено несколько свойств, которые предоставляют доступ к различным частям cookie-данных. Нас интересуют свойства <br>Name и <br>Value<br>: public string Name { get; set; } public string Value { get; set; } <br>Нетрудно догадаться, что cookie-имя содержится в свойстве <br>Name<br>, а значение — в свойстве <br>Value<br>Чтобы получить список cookie-составляющих, связанных с ответом, необходимо воспользоваться cookie-контейнером. Для этого в классе <br>HttpWebRequest определено свойство CookieContainer: public CookieContainer CookieContainer { get; set; } <br>В классе <br>CookieContainer определены различные поля, свойства и методы, которые позволяют хранить cookie-данные. Однако при создании многих приложений нет необходимости в непосредственном использовании свойства <br>CookieContainer<br>. Обычно используют коллекцию типа <br>CookieCollection<br>, получаемую из ответа. Назначение класса <br>CookieContainer<br> — обеспечить механизм хранения cookie-данных. <br>Следующая программа отображает имена и значения cookie-разделов, связанных с <br>URI-идентификатором, заданным в командной строке. При этом важно помнить, что не все <br>Web-сайты используют cookie-данные, поэтому не стоит удивляться, если вам попадется именно такой. <br>/* Отображение cookie-данных. <br> Чтобы узнать, какие cookie-данные использует интересующий вас Web-сайт, укажите его имя <br></div> <div> <br><i><b>660</b></i> <br>Часть II. Библиотека C# в командной строке. <br> Например, если эту программу назвать <br> Cookie, то после выполнения команды <br> Cookie http://MSN.COM будут отображены cookie-данные, связанные с Web-сайтом MSN.COM. */ using System; using System.Net; class CookieDemo { public static void Main(string[] args) { if(args.Length != 1) { <br> Console.WriteLine("Usage: <br>CookieDemo <br><uri>"); return; <br> } <br> // <br>Создаем WebRequest-запрос по заданному URI-адресу. <br> HttpWebRequest req = (HttpWebRequest) <br> WebRequest.Create(args[0]); <br> // <br>Получаем пустой cookie-контейнер. req.CookieContainer = new CookieContainer(); <br> // <br>Отправляем запрос и получаем ответ. <br> HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); <br> // <br>Отображаем cookie-данные. <br> Console.WriteLine("Количество cookie-разделов: " + resp.Cookies.Count); <br> Console.WriteLine("40,-20){1}", <br>"Имя", "Значение"); for(int i=0; i < resp.Cookies.Count; i++) <br> Console.WriteLine("{0, <br>-20}{1}", resp.Cookies[i].Name, resp.Cookies[i].Value); <br> // <br>Закрываем поток, содержащий ответ. resp.Close(); <br> } <br>} <br><b><span id='Использование_Свойства_LastModified'>Использование Свойства LastModified </span></b><br>Иногда нужно узнать, когда в последний раз обновлялся Web-сайт с заданным URI- адресом. С помощью класса <br>HttpWebResponse это не составляет труда, поскольку в нем определено свойство <br>LastModified<br>: public DateTime LastModified { get; } <br>Свойство <br>LastModified получает время последней URI-модификации. <br>При выполнении следующей программы отображается время и дата последней модификации Web-сайта <br>Microsoft.com<br>: <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>661</b></i> <br>// Использование свойства LastModified. using System; using System.Net; class HeaderDemo { public static void Main() { <br> HttpWebRequest req = (HttpWebRequest) <br> WebRequest.Create("http://www.Microsoft.com"); <br> HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); <br> Console.WriteLine( <br> "Время и дата последней модификации: " + resp.LastModified); resp.Close(); <br> } <br>} <br><b><span id='Учебный_проект:_программа_MiniCrawler'>Учебный проект: программа MiniCrawler </span></b><br>Чтобы показать, насколько Internet-программирование упрощается благодаря использованию классов <br>WebRequest и <br>WebReponse<br>, обратимся к разработке Web-такси. <br>Web-такси — это программа (здесь она называется <br>MiniCrawler<br>), которая просто перемещается от одной Web-страницы к другой. Web-такси в различных средствах поиска используется для составления каталога содержимого. <br>MiniCrawler<br> — довольно простая программа. Она начинает работать с заданного вами URI-адреса, а затем считывает его содержимое в расчете найти ссылку на какой-нибудь Web-документ. Если такая ссылка найдется, “водитель” Web-такси поинтересуется вашим мнением о дальнейших действиях: перейти по этой ссылке, искать другую (на той же странице) или завершить работу. <br>Программа <br>MiniCrawler имеет ряд ограничений. Во-первых, поиску подлежат только абсолютные ссылки, т.е. те, которые задаются с использованием гипертекстовой команды href=<br>. Относительные ссылки игнорируются. Во-вторых, здесь не предусмотрена возможность вернуться назад, т.е. к предыдущей ссылке, по которой был сделан переход. В- третьих, эта программа отображает только одни гиперссылки без сопутствующего содержимого. Но, несмотря на эти ограничения, Web-такси вполне функционально. К тому же, при желании вы можете расширить его возможности. И в самом деле, почему бы вам не добавить в <br>MiniCrawler какое-нибудь полезное средство? Ведь подобная попытка позволит лучше познакомиться с сетевыми классами и сетевыми C#-возможностями в целом. <br>Итак, рассмотрим код программы <br>MiniCrawler<br>: <br>// MiniCrawler: Web-такси. using System; using System.Net; using System.IO; class MiniCrawler { <br></div> <div> <br><i><b>662</b></i> <br>Часть II. Библиотека C# <br> // <br>Находим гиперссылку в строке. static string FindLink(string htmlstr, ref int startloc) <br>{ int i; int start, end; string uri = null; string lowcasestr = htmlstr.ToLower(); i = lowcasestr.IndexOf("href=\"http", startloc); if(i != -1) { start = htmlstr.IndexOf('"', i) + 1; end = htmlstr.IndexOf('"', start); uri = htmlstr.Substring(start, end-start); startloc = end; <br> } return uri; <br> } public static void Main(string[] args) { string link = null; string str; string answer; int curloc; // Содержит текущую позицию в ответе. if(args.Length != 1) { <br> Console.WriteLine("Usage: <br>MiniCrawler <br><uri>"); return; <br> } string uristr = args[0]; // Содержит текущий URI-адрес. try <br>{ do <br>{ <br> Console.WriteLine("Переход по адресу " + uristr); <br> // Создаем WebRequest-запрос по заданному URI. <br> HttpWebRequest req = (HttpWebRequest) <br>WebRequest.Create(uristr); uristr <br>= null; <br>// <br>Запрещаем дальнейшее <br> // использование этого URI-адреса. <br> // Отсылаем этот запрос и получаем ответ. <br> HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); <br> // Из потока, содержащего ответ, получаем <br> // входной поток. <br> Stream istrm <br>= resp.GetResponseStream(); <br> // Представляем входной поток <br> // в виде StreamReader-объекта. <br> StreamReader rdr = new StreamReader(istrm); <br> // Считываем целую страницу. <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>663</b></i> str <br>= rdr.ReadToEnd(); curloc <br>= <br>0; do <br>{ <br> // Находим следующий URI-адрес для перехода <br> // по гиперссылке. link = FindLink(str, ref curloc); if(link <br>!= null) <br>{ <br> Console.WriteLine("Гиперссылка найдена: " + link); <br> Console.Write("Ссылка, Дальше, Выход?"); answer <br>= <br>Console.ReadLine(); if(string.Compare(answer, "C", true) == 0) { uristr <br>= string.Copy(link); break; <br> } else if(string.Compare( answer, "B", true) == 0) { break; <br> } else if(string.Compare( answer, <br>"Д", true) == 0) { <br> Console.WriteLine("Поиск следующей ссылки."); <br> } <br> } else <br>{ <br> Console.WriteLine("Больше ссылок не найдено."); break; <br> } <br> } while(link.Length <br>> <br>0); <br> // Закрываем поток, содержащий ответ. resp.Close(); <br> } while(uristr != null); <br> } catch(WebException exc) { <br> Console.WriteLine("Сетевая ошибка: " + exc.Message + <br>"\nКод состояния: " + exc.Status); <br> } catch(ProtocolViolationException exc) { <br> Console.WriteLine("Ошибка протокола: " + exc.Message); <br> } catch(UriFormatException exc) { <br> Console.WriteLine("Ошибка в формате URI: " + exc.Message); <br> } catch(NotSupportedException exc) { <br> Console.WriteLine("Неизвестный протокол: " + exc.Message); <br> } catch(IOException exc) { <br> Console.WriteLine("I/O Error: " + exc.Message); <br> } <br> Console.WriteLine("Завершение программы MiniCrawler."); <br> } <br>} <br>Вот как выглядит фрагмент сеанса работы с программой <br>MiniCrawler<br>: <br></div> <div> <br><i><b>664</b></i> <br>Часть II. Библиотека C# <br>C:>MiniCrawler http://osborne.com <br>Переход по адресу http://osborne.com <br>Гиперссылка найдена: http://www.osborne.com/aboutus/aboutus.shtml <br>Ссылка, Дальше, Выход? Д <br>Поиск следующей ссылки. <br>Гиперссылка найдена: http://www.osborne.com/downloads/downloads.shtml <br>Ссылка, Дальше, Выход? С <br>Переход по адресу http://www.osborne.com/downloads/downloads.shtml <br>Теперь рассмотрим, как работает эта программа. URI-адрес, с которого <br>MiniCrawler начинает “извоз”, задается в командной строке. В методе <br>Main()<br> этот URI- адрес запоминается в строке uristr<br>. По нему создается запрос, а переменная uristr устанавливается равной значению null<br>, чтобы нулевая ссылка служила индикатором того, что этот URI-адрес уже использован. Затем запрос отсылается, и на него ожидается ответ. <br>Содержимое полученного ответа считывается посредством вызова метода <br>GetResponseStream()<br>, а результат этого вызова (входной поток) представляется в виде streamReader<br>-объекта. После этого вызывается метод <br>ReadToEnd()<br>, который возвращает полное содержимое потока в виде строки. <br>В полученной строке программа выполняет поиск гиперссылки. Это реализуется с помощью статического метода <br>FindLink()<br>, который также определен в классе <br>MiniCrawler<br>. Методу <br>FindLink()<br>, помимо строкового содержимого потока, также передается стартовая позиция, с которой необходимо начать поиск. Параметры, которые принимают эти значения, имеют имена htmlstr и startloc<br>, соответственно. Обратите внимание на то, что startloc является ref<br>-параметром. <span id='Метод'>Метод </span><br>FindLink() сначала создает копию “потоковой” строки в “строчном” написании, а затем ищет подстроку href="http<br>, которая означает гиперссылку. Если такая подстрока обнаружится, URI- адрес копируется в строку uri<br>, а значение параметра startloc обновляется и устанавливается равным конечной позиции найденной гиперссылки. Поскольку startloc<br>— ref<br>-параметр, то соответствующий аргумент будет обновлен и в методе <br>Main()<br>, в результате чего следующий поиск начнется с той позиции, на которой остановился предыдущий. В конечном итоге метод <br>FindLink()<br> возвращает значение строки uri<br>Если гиперссылка не обнаружится, то, поскольку uri была инициализирована null<br>- значением, метод и вернет эту нулевую ссылку, которая “засвидетельствует” неудачный исход. <br>Метод <br>Main()<br> при удачном выполнении метода <br>FindLink()<br> отображает значение найденной гиперссылки, и предлагает пользователю выбрать следующее действие из трех возможных. Пользователь может выбрать переход по ссылке (нажав клавишу <С>), заказать дальнейший поиск другой ссылки (нажав клавишу <Д>) или выйти из программы (нажав клавишу <В>). Если пользователь нажмет клавишу <С>, будет выполнен новый запрос по известному адресу с получением содержимого соответствующий страницы. И теперь в новом гипертексте будет разыскиваться очередная ссылка. Этот процесс продолжается до тех пор, пока не будут найдены все гиперссылки. <br>Возможно, вам захочется усилить описанную выше программу <br>MiniCrawler<br>Например, попробуйте автоматизировать Web-такси, заставив его посещать каждую найденную гиперссылку, не спрашивая мнения пользователя. Другими словами, укажите какую-нибудь начальную страницу и отправьте Web-такси в путь, к первой ссылке, которую он найдет. Затем (уже в новой странице) пусть оно снова отправится по первой найденной ссылке и т.д. В том случае, если ваше Web-такси попадет в “тупик”, оно должно возвратиться назад на один уровень, найти (в предыдущей странице) следующую гиперссылку и действовать по уже описанной схеме. Чтобы реализовать эту <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>665</b></i> схему, для хранения URI-адресов и текущей позиции поиска внутри URI-строки следует использовать стек. Поэтому можете воспользоваться коллекцией типа <br>Stack<br>. Можно еще усложнить задачу: попробуйте найденные гиперссылки отобразить в виде дерева. <br><b><span id='Использование_класса_WebClient'>Использование класса WebClient </span></b><br>“На десерт” кратко рассмотрим класс <br>WebClient<br>. Как упоминалось в начале этой главы, если вам нужно загрузить на удаленный компьютер (или из него) файл, то вместо классов <br>WebRequest и <br>WebResponse можно для этого использовать класс <br>WebClient<br>Достоинство класса <br>WebClient состоит в том, что он выполняет многие действия сам, освобождая таким образом вас. <br>В классе <br>WebClient определен один конструктор: public WebClient() <br>В нем также определены весьма полезные свойства (см. табл. 23.6) и методы (см. табл. 23.7). Все методы генерируют исключение типа <br>UriFormatException<br>, если заданный URI-адрес <a href="/tema-2-zaklyuchenie-i-prekrashenie-braka-4-ch/index.html" title="Тема 2 Заключение и прекращение брака (4 ч.)">окажется недействительным</a>, и исключение типа <br>WebException<br>, если во время передачи данных возникнет ошибка. <br>Таблица 23.6. Свойства, определенные в классе WebClient <br><i><b>Свойство </b></i><br><i><b>Описание </b></i><br>public string BaseAddress <br>{ get; set; } <br>Получает или устанавливает базовый адрес нужного URI, <br>По умолчанию это свойство имеет null<br>-значение. Если это свойство установлено, то адреса, заданные методами класса <br>WebClient<br>, должны интерпретироваться относительно этого базового адреса public ICredentials <br>Credentials { get; set; } <br>Получает или устанавливает регистрационную информацию. Это свойство по умолчанию имеет значение null public WebHeaderCollection <br>Headers{ get; set;} <br>Получает или устанавливает коллекцию заголовков запроса public NameValueCollection <br>QueryString { get; set;} <br>Получает или устанавливает строку запроса, состоящую из пар имя/значение, которые могут быть присоединены к запросу. Строка запроса отделяется от URI символом "<br>?<br>". <br>Если таких пар больше одной, то каждая из них отделяется символом "<br>@<br>" public WebHeaderCollection <br> ResponseHeaders{ get;} <br>Получает коллекцию заголовков ответа <br>Таблица 23.7. Методы, определенные в классе WebClient <br><i><b>Метод </b></i><br><i><b>Описание </b></i><br>public byte[] DownloadData( string <br><i>uri</i><br>) <br>Загружает информацию с Web-страницы, URI-адрес которой задается параметром <br><i>uri</i><br>. Возвращает результат в виде массива байтов public void DownloadFile( string <br><i>uri</i><br>, string <br><i>fname</i><br>) <br>Загружает информацию с Web-страницы, URI-адрес которой задается параметром <br><i>uri</i><br>, и сохраняет результат в файле, имя которого задается параметром <br><i>fname</i><br>public Stream OpenRead( string <br><i>uri</i><br>) <br>Возвращает входной поток, информацию из которого можно прочитать с использованием URI-адреса, заданного параметром <br><i>uri</i><br>. После завершения считывания этот поток необходимо закрыть <br></div> <div> <br><i><b>666</b></i> <br>Часть II. Библиотека C# <br>Окончание табл. 23.7 <br><i><b>Метод </b></i><br><i><b>Описание </b></i><br>public Stream OpenWrite( string <br><i>uri</i><br>)<br>Возвращает выходной поток, в который можно записать информацию с помощью URI-адреса, заданного параметром <br><i>uri</i><br>. После завершения записи этот поток необходимо закрыть public Stream OpenWrite( string <br><i>uri</i><br>, string <br><i>how</i><br>)<br>Возвращает выходной поток, в который можно записать информацию с использованием URI-адреса, заданного параметром <br><i>uri</i><br>. После завершения записи этот поток необходимо закрыть. Строка, переданная в параметре <br><i>how</i><br>, задает способ записи этой информации public byte[] UploadData( string <br><i>uri</i><br>, byte[] <br><i>info</i><br>)<br>Записывает информацию, заданную параметром <br><i>info</i><br>, по <br>URI-адресу, заданному параметром <br><i>uri</i><br>. Возвращает ответ public byte[] UploadData( string <br><i>uri</i><br>, string <br><i>how</i><br>, byte[] <br><i>info</i><br>)<br>Записывает информацию, заданную параметром <br><i>info</i><br>, по <br>URI-адресу, заданному параметром <br><i>uri</i><br>. Возвращает ответ. Строка, переданная в параметре <br><i>how</i><br>, задает способ записи этой информации public byte[] UploadFile( string <br><i>uri</i><br>, string <br><i>fname</i><br>)<br>Записывает информацию из файла имя которого задается параметром <br><i>fname</i><br>, по URI-адресу, заданному параметром <br><i>uri</i><br>. Возвращает ответ public byte[] UploadFile( string <br><i>uri</i><br>, string <br><i>how</i><br>, string <br><i>fname</i><br>)<br>Записывает информацию из файла, имя которого задается параметром <br><i>fname</i><br>, по URI-адресу, заданному параметром <br><i>uri</i><br>. Возвращает ответ. Строка, переданная в параметре <br><i>how</i><br>, задает способ записи этой информации public byte[] UploadValues( string <br><i>uri</i><br>, <br> HameValueCollection <br><i>vals</i><br>)<br>Записывает значения, хранимые в коллекции, заданной параметром <br><i>vals</i><br>, по URI-адресу, заданному параметром <br><i>uri</i><br>. Возвращает ответ public byte[] UploadValues( string <br><i>uri</i><br>, string <br><i>how</i><br>, <br> NameValueCollection <br><i>vals</i><br>)<br>Записывает значения, хранимые в коллекции, заданной параметром <br><i>vals</i><br>, по URI-адресу, заданному параметром <br><i>uri</i><br>. Возвращает ответ Строка, переданная в параметре <br><i>how</i><br>, задает способ записи этой информации <br>Использование класса <br>WebClient для загрузки данных в файл демонстрируется в следующей программе: <br>// Использование класса WebClient для загрузки <br>// информации в файл. using System; using System.Net; using System.IO; class WebClientDemo { public static void Main() { <br> WebClient user = new WebClient(); string uri = "http://www.osborne.com"; string fname = "data.txt"; try <br>{ <br> Console.WriteLine( <br> "Загрузка данных из Web-страницы " + uri + <br> " в файл " + fname); user.DownloadFile(uri, fname); <br></div> <div> <br>Глава 23. Сетевые возможности и использование Internet <br><i><b>667</b></i> <br>} catch(WebException exc) { <br> Console.WriteLine(exc); <br> } catch(UriFormatException exc) { <br> Console.WriteLine(exc); <br> } <br> Console.WriteLine("Загрузка завершена."); <br> } <br>} <br>Эта программа загружает информацию с Web-сайта <br>Osborne.com и помещает ее в файл с именем data.txt<br>. Обратите внимание на то, что все это реализуется очень небольшим количеством строк кода, в число которых включены и те, которые обеспечивают обработку возможных исключений. Приведенная программа позволяет загрузить информацию с любого URI-адреса: для этого достаточно изменить соответствующим образом строку, заданную переменной uri<br>Несмотря на то что классы <br>WebReguest и <br>WebResponse дают программисту большие возможности для управления и доступ к более обширной информации, средств, инкапсулированных классом <br>WebClient<br>, вполне достаточно для потребностей многих приложений. Он особенно полезен в том случае, если приложение должно обеспечить лишь загрузку информации из Web-пространства. Например, с помощью класса <br>WebClient вы могли бы организовать получение обновленной документации по интересующим вас продуктам. <br></div> <div> <br>Полный справочник по <br><b><span id='Часть_III_Применение_языка_C'>Часть III </span></b><br><b>Применение языка C# </b><br>В части III представлены три C#-приложения. Первое иллюстрирует создание компонентов и управление ими. Поскольку многие средства C# были разработаны специально для того, чтобы упростить их создание, нетрудно предположить, что компоненты составляют важную часть программирования на C#. Во втором приложении демонстрируется создание Windows- программы с помощью классов, определенных в пространстве имен System.Windows.Forms. Наконец, третье приложение представляет собой пример <br>“чистого кода”: речь идет о применении синтаксического анализа методом рекурсивного спуска к вычислению алгебраических выражений. <br></div> <div> <br></div> <div> <br>Полный справочник по <br></uri></uri></enter></enter>
    1   ...   41   42   43   44   45   46   47   48   ...   52


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