Написать простенький веб-сервер и клиент к нему - C#
Формулировка задачи:
Доброе всем время суток. Мне нужно написать простенький веб-сервер и клиент к нему. Клиент отправляет GET-запрос на сервер, сервер посылает в ответ в виде XML. Далее XML парсится и его значения переходят в RichTextBox'ы.
Веб-сервер я стянул отсюда http://habrahabr.ru/post/120157/
Вот код:
Вот код моего недо-клиента, который должен получать и обрабатывать ответ сервера. Я слабо представляю, как это должно выглядеть, поэтому просто попытался написать нечто, что будет считывать xml-файл и раскидывать его значения по тектбоксам.
По идее, нужно написать что-то вроде:
вот сам xml:
Проблема в том, что я не представляю себе, что нужно передать серверу в качестве запроса в GET, и как сервер должен передать XML-код мне обратно, а я считать его.
В гугле был, похожие темы видел, но не докурил, не могу понять сам принцип, прошу помощи в общем)
using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using System.Net; using System.Threading; using System.Text.RegularExpressions; using System.IO; using System.Xml.Linq; namespace HTTPServer { // Класс-обработчик клиента class Client { // Отправка страницы с ошибкой private void SendError(TcpClient Client, int Code) { // Получаем строку вида "200 OK" // HttpStatusCode хранит в себе все статус-коды HTTP/1.1 string CodeStr = Code.ToString() + " " + ((HttpStatusCode)Code).ToString(); // Код простой HTML-странички string Html = "<html><body><h1>" + CodeStr + "</h1></body></html>"; // Необходимые заголовки: ответ сервера, тип и длина содержимого. После двух пустых строк - само содержимое string Str = "HTTP/1.1 " + CodeStr + "\nContent-type: text/html\nContent-Length:" + Html.Length.ToString() + "\n\n" + Html; // Приведем строку к виду массива байт byte[] Buffer = Encoding.ASCII.GetBytes(Str); // Отправим его клиенту Client.GetStream().Write(Buffer, 0, Buffer.Length); // Закроем соединение Client.Close(); } // Конструктор класса. Ему нужно передавать принятого клиента от TcpListener public Client(TcpClient Client) { // Объявим строку, в которой будет хранится запрос клиента string Request = ""; // Буфер для хранения принятых от клиента данных byte[] Buffer = new byte[1024]; // Переменная для хранения количества байт, принятых от клиента int Count; // Читаем из потока клиента до тех пор, пока от него поступают данные while ((Count = Client.GetStream().Read(Buffer, 0, Buffer.Length)) > 0) { // Преобразуем эти данные в строку и добавим ее к переменной Request Request += Encoding.ASCII.GetString(Buffer, 0, Count); // Запрос должен обрываться последовательностью \r\n\r\n // Либо обрываем прием данных сами, если длина строки Request превышает 4 килобайта // Нам не нужно получать данные из POST-запроса (и т. п.), а обычный запрос // по идее не должен быть больше 4 килобайт if (Request.IndexOf("\r\n\r\n") >= 0 || Request.Length > 4096) { break; } } // Парсим строку запроса с использованием регулярных выражений // При этом отсекаем все переменные GET-запроса Match ReqMatch = Regex.Match(Request, @"^\w+\s+([^\s\?]+)[^\s]*\s+HTTP/.*|"); // Если запрос не удался if (ReqMatch == Match.Empty) { // Передаем клиенту ошибку 400 - неверный запрос SendError(Client, 400); return; } // Получаем строку запроса string RequestUri = ReqMatch.Groups[1].Value; // Приводим ее к изначальному виду, преобразуя экранированные символы // Например, "%20" -> " " RequestUri = Uri.UnescapeDataString(RequestUri); // Если в строке содержится двоеточие, передадим ошибку 400 // Это нужно для защиты от URL типа [url]http://example.com/file.txt[/url] if (RequestUri.IndexOf("..") >= 0) { SendError(Client, 400); return; } // Если строка запроса оканчивается на "/", то добавим к ней index.html if (RequestUri.EndsWith("/")) { RequestUri += "index.html"; //RequestUri += "index.xml"; } string FilePath = "www/" + RequestUri; // Если в папке www не существует данного файла, посылаем ошибку 404 if (!File.Exists(FilePath)) { SendError(Client, 404); return; } // Получаем расширение файла из строки запроса string Extension = RequestUri.Substring(RequestUri.LastIndexOf('.')); // Тип содержимого string ContentType = ""; // Пытаемся определить тип содержимого по расширению файла switch (Extension) { case ".htm": case ".html": ContentType = "text/html"; break; case ".css": ContentType = "text/stylesheet"; break; case ".js": ContentType = "text/javascript"; break; case ".jpg": ContentType = "image/jpeg"; break; case ".jpeg": case ".png": case ".gif": ContentType = "image/" + Extension.Substring(1); break; default: if (Extension.Length > 1) { ContentType = "application/" + Extension.Substring(1); } else { ContentType = "application/unknown"; } break; } // Открываем файл, страхуясь на случай ошибки FileStream FS; try { FS = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (Exception) { // Если случилась ошибка, посылаем клиенту ошибку 500 SendError(Client, 500); return; } // Посылаем заголовки string Headers = "HTTP/1.1 200 OK\nContent-Type: " + ContentType + "\nContent-Length: " + FS.Length + "\n\n"; byte[] HeadersBuffer = Encoding.ASCII.GetBytes(Headers); Client.GetStream().Write(HeadersBuffer, 0, HeadersBuffer.Length); // Пока не достигнут конец файла while (FS.Position < FS.Length) { // Читаем данные из файла Count = FS.Read(Buffer, 0, Buffer.Length); // И передаем их клиенту Client.GetStream().Write(Buffer, 0, Count); } // Закроем файл и соединение FS.Close(); Client.Close(); } } class Server { TcpListener Listener; // Объект, принимающий TCP-клиентов // Запуск сервера public Server(int Port) { Listener = new TcpListener(IPAddress.Any, Port); // Создаем "слушателя" для указанного порта Listener.Start(); // Запускаем его // В бесконечном цикле while (true) { // Принимаем нового клиента TcpClient Client = Listener.AcceptTcpClient(); // Создаем поток Thread Thread = new Thread(new ParameterizedThreadStart(ClientThread)); // И запускаем этот поток, передавая ему принятого клиента Thread.Start(Client); } } static void ClientThread(Object StateInfo) { // Просто создаем новый экземпляр класса Client и передаем ему приведенный к классу TcpClient объект StateInfo new Client((TcpClient)StateInfo); } // Остановка сервера ~Server() { // Если "слушатель" был создан if (Listener != null) { // Остановим его Listener.Stop(); } } static void Main(string[] args) { // Создадим новый сервер на порту 88 new Server(88); } } }
private void button2_Click(object sender, EventArgs e) { var doc = XDocument.Load(@"C:\XMLFile1.xml"); //если запустить так, все отлично парсится //var doc = XDocument.Load(@"http://127.0.0.1:88/index.xml"); /*а если так, то запускается, но не работает: "The server committed a protocol violation. Section=ResponseStatusLine" */ label3.Text = (doc.Root.Element("incident").Element("category").Attribute("name").Value); richTextBox1.Text = (doc.Root.Element("incident").Element("description").Value); richTextBox2.Text = (doc.Root.Element("incident").Element("place").Attribute("x").Value); richTextBox3.Text = (doc.Root.Element("incident").Element("place").Attribute("y").Value); richTextBox4.Text = (doc.Root.Element("incident").Element("place").Attribute("street").Value); richTextBox5.Text = (doc.Root.Element("incident").Element("place").Attribute("numhome").Value); richTextBox6.Text = (doc.Root.Element("incident").Element("place").Attribute("numflat").Value); textBox2.Visible = true; timer1.Enabled = true; }
private void button1_Click(object sender, EventArgs e) { try { var url = string.Format(@"http://{0}/", textBox1.Text); System.Net.WebRequest reqGET = System.Net.WebRequest.Create(url); var resp = reqGET.GetResponse(); System.IO.Stream stream = resp.GetResponseStream(); label5.Text = (new System.IO.StreamReader(stream)).ReadToEnd(); } catch (WebException ea) { //MessageBox.Show("Ошибка"); label1.Text = (ea.GetType().ToString()); //что-то типа лога с ошибками } }
<?xml version="1.0" encoding="utf-8"?> <result> <incident id="12323"> <category id="12" name="North"/> <description> TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT </description> <place x="78.34534" y="56.4564566" street="Lenina" numhome="387" numflat="73"/> </incident> </result>
Решение задачи: «Написать простенький веб-сервер и клиент к нему»
textual
Листинг программы
private void button1_Click(object sender, EventArgs e) { TcpClient tcpClient; NetworkStream networkStream; StreamReader streamReader; StreamWriter streamWriter; try { var url = string.Format(@"http://{0}/", textBox1.Text); //считали значение URL из текстбокса System.Net.WebRequest reqGET = System.Net.WebRequest.Create(url); //постали get-запрос на основе URL var resp = reqGET.GetResponse(); // получили ответ System.IO.Stream stream = resp.GetResponseStream(); // ? var nov = new System.IO.StreamReader((stream), Encoding.UTF8); label5.Text = (new System.IO.StreamReader(stream)).ReadToEnd(); // сюда по идее должна вставлять та самая передаваемая строчка, однако catch подхватывает ошибку и ничего не происходит } catch (WebException ea) { label1.Text = (ea.GetType().ToString()); } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д