C#   Уроки программирования с нуля. Си-шарп для чайников   C#

Здравствуйте, гость!
Вход
Регистрация


Протокол HTTP в Си-Шарп. Классы HttpWebRequest и HttpWebResponse
В этом уроке будет рассмотрен протокол HTTP и базовая работа с ним в Си-шарп.

HTTP (HyperText Transfer Protocol) – это протокол передачи данных (изначально гипертекстовых данных в формате HTML, потом произвольных данных) прикладного уровня, используемый в World Wide Web (WWW).

Протокол HTTP работает по технологии клиент-сервер. Клиентом обычно выступает веб-браузер, а сервером – веб-сервер. Клиент формирует и делает запрос к серверу, и тот, обработав запрос, возвращает ответ клиенту.

Объектом, над которым происходит работа протокола HTTP, является ресурс, на который указывает URI в запросе клиента. URI (Uniform Resource Identifier) – унифицированный идентификатор ресурса, простыми словами, это то, что указывается в строке браузера – имя запрашиваемого ресурса (страница, изображение, и т.д.).

Структура HTTP-сообщения имеет следующий вид:

[стартовая-строка]
[заголовок-сообщения1]
[заголовок-сообщения2]


[тело-сообщения]


Стартовая строка для запроса и ответа отличаются.
Для запроса она имеет такую структуру:

[Метод] [URI] HTTP/[Версия]


Здесь метод – название запроса, одно слово заглавными буквами, наиболее часто используются GET, POST, HEAD.

URI – идентификатор запрашиваемого ресурса.

Версия – цифры, разделенные точкой (например 1.1).

Для главной страницы этого сайта стартовая строка будет иметь такой вид:

GET / HTTP/1.1


Для ответа стартовая строка выглядит так:

HTTP/Версия [Код Состояния] [Пояснение]


Код Состояния – это трехзначный цифровой код, который определяет результат запроса. Например, если клиент запросил при помощи метода GET некий ресурс, и сервер его смог предоставить, такое состояние имеет код 200. Если же на сервере нет запрашиваемого ресурса, он вернет код состояния 404. Есть и много других состояний.

Пояснение – это текстовое отображение кода состояния, для упрощенного понимания человека. Для кода 200 пояснение имеет вид «OK».

Ответ на запрос главной страницы сайта имеет такой вид:

HTTP/1.1 200 OK


В таблице 1 приведены распространенные коды состояния:

Таблица 1
КодОписание
200Хорошо. Успешный запрос
301Запрошенный ресурс был окончательно перенесен на новый URI
302Запрошенный ресурс был временно перенесен на другой URI
400Неверный запрос - запрос не понят сервером из-за наличия синтаксической ошибки
401Несанкционированный доступ — у пользователя нет прав для доступа к запрошенному документу.
404Не найдено - сервер понял запрос, но не нашёл соответствующего ресурса по указанному URI
408Время ожидания сервером передачи от клиента истекло
500Внутренняя ошибка сервера—ошибка помешала HTTP-серверу обработать запрос


HTTP-заголовки

Заголовки HTTP – это строки в HTTP-сообщении в формате «имя: значение». Другими словами их можно назвать метаданными (информация об используемых данных) HTTP-сообщения.

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

Заголовки запросов

Приведу некоторые примеры заголовков запросов:

Заголовок Referer – URI ресурса, с котрого клиент сделал запрос на сервер. Перейдя со страницы1 на страницу2, Referer будет содержать адрес страницы1. Этот заголовок может быть полезным, например, для того, чтобы отследить по каким поисковым запросам посетители попали на ваш сайт. Или сервер может как либо иначе обрабатывать запрос, если Referer не тот, который ожидается.

Перейдя с главной страницы сайта на любую другую страницу, Referer будет выглядеть так:

Referer: http://mycsharp.ru/


Заголовок Accept используется для того, чтобы клиент сообщил серверу, какие типы контента он поддерживает. Типы указываются в формате тип/подтип через запятую:

Accept: text/html, text/plain, image/jpeg
Accept: image/jpg, image/gif


Если тип не может быть обработан, возвращается HTTP-код 406 «Not acceptable».

Заголовок User-Agent содержит информацию о клиентском приложении. Обычно это имя браузера, его версия и платформу. В первую очередь этот заголовок нужен для корректного отображения страницы. Браузеров есть много, много версий и не все могут одинаково отображать контент, web-программисты учитывают эту информацию и выдают различным браузерам различные скрипты/стили:

User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:37.0) Gecko/20100101 Firefox/37.0


Заголовок Content-length содержит длину передаваемых данных в байтах при использовании метода передачи POST. При методе GET он не устанавливается.

Content-Length: 2803


Заголовки ответов

Заголовок Server содержит информацию о программном обеспечении, которое использует сервер:

Server: Microsoft-IIS/7.0


Заголовок Content-Type указывает тип данных, которые отправляются клиенту, или которые могли бы отправиться, используя метод HEAD.

Content-Type : text/html; charset=utf-8
Content-Type : text/plain
Content-Type: image/jpeg


Общие заголовки

Заголовок Date указывает дату и время создания сообщения:

Date: Mon, 06 Apr 2015 17:09:39 GMT


Заголовок Content-Language содержит список языков, для которых предназначается контент.

Content-Language: en, ru


Тело HTTP cообщения

Тело (message-body) используется для передачи тела объекта, связанного с запросом или ответом. Обычно это сгенерированный html-код, который браузер потом будет отображать. Тело обязательно отделяется от заголовков пустой строкой.

Теперь перейдем к программированию.

Классы HttpWebRequest и HttpWebResponse

Платформа .NET Framework для работы с протоколом HTTP предоставляет два основных класса. Один из них отвечает за запрос – класс HttpWebRequest, а другой за ответ – HttpWebResponse.

Приведу пример простой программы, с использованием данных классов, которая получает из интернета указанную страничку:

static void Main()
{
   string uri = "http://mycsharp.ru/post/49/2015_03_02_setevoe_programmirovanie_v_si-sharp.html";
   HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
   HttpWebResponse response = (HttpWebResponse)request.GetResponse();
   StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
   Console.WriteLine(reader.ReadToEnd());
   Console.ReadLine();
}

Сначала создается объект запроса при помощи статического метода Create класса WebRequest, в который передается адрес запрашиваемого ресурса. При этом возвращаемый объект необходимо привести к типу HttpWebRequest, потому как метод Create возвращает различный объект запроса, основываясь на том, какой URI ему передали, это может быть, как в нашем случае, HTTP запрос, так и запрос к файловой системе (при этом возвращается объект FileWebRequest).

Дальше мы создаем объект ответа HttpWebResponse путем вызова метода GetResponse у объекта запроса (при этом приводим его к типу HttpWebResponse). При вызове этого метода, на сервер отправляется запрос, и в результате мы получаем объект HttpWebResponse который содержит HTTP-заголовки, а также поток, с которого мы можем считать тело ответа.

Дальше создается объект чтения потока StreamReader, в его конструктор передается поток ответа, который возвращает метод GetResponseStream, указываем необходимую кодировку, и выводим данные на экран. В результате мы увидим HTML код запрашиваемой страницы.

Работа с HTTP-заголовками

Для работы с заголовками у обоих классов HttpWebRequest и HttpWebResponse есть свойство Headers (объект типа WebHeaderCollection) которое предоставляет информацию о заголовках запроса и ответа соответственно. Для добавления или установки заголовков используются методы Add и Set. Метод Add принимает один строковый аргумент – заголовок полностью в формате "имя: значение":

request.Headers.Add("Content-Language: en, ru");


Метод Set принимает два строковых аргумента – имя и значение:

request.Headers.Set("Content-Language", "en, ru");


Использовать можно любой из этих методов, но кроме такой "ручной" установки заголовков есть еще возможность задать значения некоторых распространенных заголовков, используя соответствующие свойства в классах HttpWebRequest и HttpWebResponse. Например, установка заголовка Referer:

request.Referer = "http://google.com";


Доступ к конкретному заголовку осуществляется при помощи той же коллекции Headers (коллекция пар имя-значение WebHeaderCollection). В квадратных скобках указываем имя заголовка, и получаем его значение:

Console.WriteLine(response.Headers["date"]); // Tue, 07 Apr 2015 17:29:04 GMT


Считать все заголовки можно так:

foreach(string header in response.Headers)
Console.WriteLine("{0}: {1}", header, response.Headers[header]);


Вывод будет таким:

Content-Length: 77352
Cache-Control: private
Content-Type: text/html; charset=utf-8
Date: Tue, 07 Apr 2015 17:29:04 GMT
Set-Cookie: ASP.NET_SessionId=3nq4lu3qep3bb3vj2gnhmqdf; path=/; HttpOnly
Server: Microsoft-IIS/7.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET


В примерах выше все запросы выполнялись методом "GET".У классов HttpWebRequest и HttpWebResponse есть свойство Method. Для запроса оно по умолчанию установлено как "GET", но его можно изменить, например на "POST", об этом методе и будет следующий урок. Для ответа же это свойство только на чтение.

Домашнее задание

Ваша программа должна выводить в консоль заголовки уроков с главной страницы сайта (те, что в центральной колонке, 8 последних). Кроме этого, я настроил сервер так, что если заголовок user-agent при запросе к главной странице сайта равен значению "lesson34", то в ответ вы получите не главную страницу, а страницу контактов. Установите значение "lesson34" для этого заголовка и убедитесь, что это работает.

Понравилась статья? Подпишись на рассылку и узнавай первым о новых уроках по почте!


Поделиться с друзьями:
19 апр 2015 19:45
wElenacag 26 май 2017 00:09
Наш сервис предоставляет настоящие лайки на фотографии заказчиков, которые готовы платить за качество.

Именно для этого мы и набираем удалённых сотрудников, которые будут выполнять работу, то есть ставить лайки и получить за это деньги.

Чтобы стать нашим удалённым сотрудником и начать ставить лайки, зарабатывая при этом 45 рублей за 1 поставленный лайк,

достаточно просто зарегистрироваться на нашем сервисе. > www.oplata-vklike.tk <

Вывод заработанных средств ежедневно в течении нескольких минут.

ShawnRag 25 май 2017 11:14
Christmas Piano
Christmas Background Music
Perfect instrumental background music for romantic and sentimental films, presenting your business, new products or your company in general with an optimistic and motivational touch.
Visit site: https://audiojungle.net/item/christmas-piano/19056234/

https://audiojungle.net/user/commercial_music

https://audiojungle.net/user/corporate_sound

https://audiojungle.net/user/elijah_studio

https://audiojungle.net/user/ie_sound

https://audiojungle.net/user/momentumofmelody
===========

segorcag 18 май 2017 20:43
Предлагаем Вам работу без вложений, на системе автоматического приёма и обработки заказов.

Мы предоставляем:

- Наш лицезионный софт.
- документы со всей необходимой доп. информацией.
- постоянная техническая поддержка.

Оплата от 5500 в день. Выплаты ежедневно.

Более подробная информация на нашем сайте >> obrabotka-zakazov.tk <<

fr46456ygdcs 30 мар 2017 16:37
cr346467rhsvczxvmkaskoADKM FD453456YGFFFFdd bvu67i4yhgfdh

valermth 06 фев 2017 15:15

I may subscribe.

volest 02 фев 2017 11:19

Please allow me recognize so that

pegorcag 02 фев 2017 11:00
Высокооплачиваемая работа не выходя из дома.
Мы предлагаем: Достойная зарплата без задержек, справка 2-НДФЛ, карьерный рост, бесплатное обучение,
свободный график, страховые взносы в Пенсионный фонд, официальный договор (по желанию).
График работы, Вы устанавливаете самостоятельно, по своим возможностям.
Ваш возраст и образование значения не имеют.
Обязательные условия: наличие компьютера и интернета.
Ваши действия:
1. На сайте ( off-rabota.tk ) скачайте и установите приложение.
2. Ознакомьтесь с содержимым.
3. Пройдите несложную регистрацию.
4. Обязательно, пройдите курсы обучения. (Бесплатно)
5. Начинайте зарабатывать!
Зарплату мы перечисляем только на банковскую карту любой платёжной системы.
(Для работы советуем оформить отдельную карту)
ВНИМАНИЕ! Весь процесс регистрации, обучения совершенно бесплатны. Не попадитесь в руки мошенников!

-----JGHHJ16FU16G1U6F51J6F1J6R1UY6F5Y-----

Максим 12 июл 2016 10:33
Саша
---
Я всем советую заниматься практикой, это даст вам намного больше, и знания, и опыт, с деталями языка уже походу разберётесь, базы тут достаточно. Начните делать что-то конкретное, даже если оно покажется трудным, и что-то вы не знаете - ищите в интернете, там есть всё. Например, игру какую-нибудь простую, пятнашки там, крестики нолики (на формах или wpf, да, об этом уроков не было, но нужно уметь быстро осваивать технологии, а эти конкретно ничего сложного), или программку, которая будет показывать погоду/результаты футбола (парсить из интернета).

Саша 10 июл 2016 02:18
Спасибо за хорошую работу.
Очень жаль что нет новых уроков :(
У меня предложение. Может вы напишите что вы еще планировали опубликовать? Другими словами, что еще необходимо знать о C#? Дальнейшую программу обучения? А мы уже дальше самостоятельно найдем необходимый материал.

Максим 01 июл 2016 21:48
Диманиак
---
Да, сам понимаю, немного забросил сайт, может закончу дело которым занимаюсь и возобновлюсь здесь. Вижу, что люди благодарят денюжкой иногда, приятно, спасибо.

Диманиак 30 июн 2016 09:52
Уже больше года нет новых уроков - дождемся ли?

Мгер 04 апр 2016 14:28
когда следующий урок?

VladAndronik 31 мар 2016 23:09
Спасибо за уроки!! Будут еще?

Катя 14 ноя 2015 12:01
POST запрос не возвращает данные. После передачи параметров должна возвратиться страница sinonimus.ru/index.php/index.php#final_text с таблицей синонимов вместо этого возвращается старая и пустая. Прилагаю код ,помогите разобраться. В коде использую библиотеку XNet.
Возможно вы знаете более эффективный код для запросов на подобные сайты.

public string PostWebHTML(string regword)
{



using (var request = new HttpRequest())
{

request.UserAgent = HttpHelper.ChromeUserAgent();
CookieDictionary cookie = new CookieDictionary(false);
request.Cookies = cookie;


request.Referer = "http://sinonimus.ru";
request.KeepAlive = true;


var reqParams = new RequestParams();

reqParams["slovo"] = HttpHelper.UrlEncode(regword);
reqParams["sin_dict=all"] = "all";




string content = request.Post("http://sinonimus.ru/index.php", reqParams).ToString();

return content;

}



}

Anton 07 ноя 2015 17:13
Добрий день. Хотів запитати чи будуть уроки по формах в сі шарп ?

Максим 22 сен 2015 11:10
Роман
---
Возможно будут

Роман 18 сен 2015 11:50
Благодарю вас за труд. Скажите, пожалуйста, а будут уроки по работе с базами данных?

ROOT 21 авг 2015 19:45
Ребята, администратор!
Подскажите, пожалуйста в одном деле. В разделе "Контакты" есть ссылка на видеокурс по вёрстке сайтов. Кто-нибудь покупал его? Хотелось бы узнать качество данного материала. Прошу ответить или здесь или написать на мой e-mail: ilyaaxenov1999@yandex.ru . Заранее спасибо!

Виктор 17 авг 2015 23:02
Я тут подумал...

<h1>Тест на XSS<h1>

Максим 04 авг 2015 10:45
Илья
---
Будут

Илья 03 авг 2015 21:25
А что все? Больше уроков не будет?

Азиз 21 май 2015 07:06
Максим
---

Благодарю! Первый способ помог!

Максим 20 май 2015 22:46
Азиз
---
Попробуйте один из вариантов:
1. Панель управления - Часы, язык, регион - Язык и региональные стандарты - дополнительно - поле "Язык программ, не поддерживающих Юникод - конопка "изменить язык системы", выбираем русский - перезагрузка.

2. В свойствах консоли выбрите шрифт Lucida Console.

Азиз 20 май 2015 22:19
Кстати, Максим, не могли бы вы мне помочь?
У меня проблемы с кодировкой в консоли. Использую русскую Windows 8.1. Русские буквы показывает иероглифами.
Пробовал:
Console.OutputEncoding = Encoding.UTF8;

Console.OutputEncoding = Encoding.Unicode;

Console.OutputEncoding = Encoding.GetEncoding(1251);

Console.OutputEncoding = Encoding.Default;

Console.OutputEncoding = Encoding.ASCII;

Ничего из этого не помогло, меняется только тип иероглифов(или превращаются в знаки вопроса) :(

Азиз 20 май 2015 22:08
Вот готовый код, без тегов:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://mycsharp.ru");
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader reader = new StreamReader(response.GetResponseStream());
string html = reader.ReadToEnd();
MatchCollection matches = Regex.Matches(html,"<h2>.*?</h2>",RegexOptions.Singleline);
foreach (Match element in matches) {

string header = Regex.Replace(element.Value, "<.*?>","");
Console.WriteLine(header);
Console.WriteLine();
}
Console.ReadLine();

Азиз 20 май 2015 22:02
Максим
---

Прочитал про жадный и ленивый поиск, теперь все понял! Благодарю за помощь, кстати сайт отличный!

Максим 20 май 2015 20:30
Азиз
---
У вас используется "жадный" поиск - получается одно большое совпадение, в которое входит последнее "</h2>". Нужно использовать "ленивый" поиск, вот так:
"<h2>.*?</h2>"

Азиз 20 май 2015 17:27
Здравствуйте!
Пожалуйста помогите, не знаю почему берет много лишнего.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://mycsharp.ru");
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader reader = new StreamReader(response.GetResponseStream());
string html = reader.ReadToEnd();
MatchCollection matches = Regex.Matches(html,"<h2>.*</h2>",RegexOptions.Singleline);
foreach (Match element in matches) {

Console.WriteLine(element.Value);
}
Console.ReadLine();

Максим 24 апр 2015 16:12
Диманиак
---
Можно так:

static void Main(string[] args)
{
string uri = "http://mycsharp.ru/";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
Regex myReg = new Regex("(?<=color=\"\\#454545\" size=\"6\">)([^<]+)");
MatchCollection matches = myReg.Matches(reader.ReadToEnd());
foreach (Match m in matches)
Console.WriteLine(m.Value);
Console.ReadLine();
}

"?<=" - это означает не включать в результат последовательность символов что справа

Диманиак 23 апр 2015 08:30
Хотелось бы сделать выборку названий уроков полностью с использованием регулярных выражений, но пока не хватает опыта.

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

Если автор будет так добр и подскажет как - буду признателен.


using System;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string uri = "http://mycsharp.ru/";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

//Console.BufferHeight = 500; // раскомментировать, чтобы
//request.UserAgent = "lesson34"; // увидеть разницу (пустой вывод)
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);

Regex myReg = new Regex("<a id=\"ContentPlaceHolder1_DataListPosts_HyperLink1");

while (!reader.EndOfStream)
{
string str = reader.ReadLine();

if (myReg.IsMatch(str))
{
int posA = str.IndexOf("\"6\">") + 4; // 4 = размер текста '"6">'
int posB = str.IndexOf("</font>");
Console.WriteLine(str.Substring(posA, posB - posA));
}
}
Console.ReadLine();
}
}
}


Добавить комментарий:

Имя (обязат.)
E-mail (обязат., не публикуется)


Для вставки ваших программ пользуйтесь кнопкой "исходный код"
Вёрстка сайта с нуля

Уникальный Видеокурс!

"Научись верстать сайты и заработай на этом!"

Получить видеокурс

Подпишись на курс по программированию, и узнавай первым о новых уроках!

RSS подписка Страничка Вконтакте Мы в Twitter

Ошибка в тексте? Выделите ее мышкой и нажмите Ctrl+Enter
Поблагодарить автора: Номер карты (ПриватБанк)
5168 7572 4170 8660
WebMoney
R372544961915 U685637142028 Z999792764387
Наверх
Система Orphus