Работа с GET(POST) запросом по протоколу http - C#

Узнай цену своей работы

Формулировка задачи:

Проблема следующая: на C# создан http сервер, к нему подключаются клиенты, но пока кроме вывода строки It Works у него нет более функционала. Задача сервера - принять клиента, отправить ему файл и разорвать соединение, дожидаясь других подключений. Вопрос, как передать файл запросом по протоколу http? Код программы:
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net.Sockets;
  5. using System.Net;
  6. using System.Threading;
  7. using System.Text.RegularExpressions;
  8. using System.IO;
  9. namespace HTTPServer
  10. {
  11. // Класс-обработчик клиента
  12. class Client
  13. {
  14. // Отправка страницы с ошибкой
  15. private void SendError(TcpClient Client, int Code)
  16. {
  17. // Получаем строку вида "200 OK"
  18. // HttpStatusCode хранит в себе все статус-коды HTTP/1.1
  19. string CodeStr = Code.ToString() + " " + ((HttpStatusCode)Code).ToString();
  20. // Код простой HTML-странички
  21. string Html = "<html><body><h1>" + CodeStr + "</h1></body></html>";
  22. // Необходимые заголовки: ответ сервера, тип и длина содержимого. После двух пустых строк - само содержимое
  23. string Str = "HTTP/1.1 " + CodeStr + "\nContent-type: text/html\nContent-Length:" + Html.Length.ToString() + "\n\n" + Html;
  24. // Приведем строку к виду массива байт
  25. byte[] Buffer = Encoding.ASCII.GetBytes(Str);
  26. // Отправим его клиенту
  27. Client.GetStream().Write(Buffer, 0, Buffer.Length);
  28. // Закроем соединение
  29. Client.Close();
  30. }
  31. // Конструктор класса. Ему нужно передавать принятого клиента от TcpListener
  32. public Client(TcpClient Client)
  33. {
  34. // Объявим строку, в которой будет хранится запрос клиента
  35. string Request = "";
  36. // Буфер для хранения принятых от клиента данных
  37. byte[] Buffer = new byte[1024];
  38. // Переменная для хранения количества байт, принятых от клиента
  39. int Count;
  40. // Читаем из потока клиента до тех пор, пока от него поступают данные
  41. while ((Count = Client.GetStream().Read(Buffer, 0, Buffer.Length)) > 0)
  42. {
  43. // Преобразуем эти данные в строку и добавим ее к переменной Request
  44. Request += Encoding.ASCII.GetString(Buffer, 0, Count);
  45. // Запрос должен обрываться последовательностью \r\n\r\n
  46. // Либо обрываем прием данных сами, если длина строки Request превышает 4 килобайта
  47. // Нам не нужно получать данные из POST-запроса (и т. п.), а обычный запрос
  48. // по идее не должен быть больше 4 килобайт
  49. if (Request.IndexOf("\r\n\r\n") >= 0 || Request.Length > 4096)
  50. {
  51. break;
  52. }
  53. }
  54. // Парсим строку запроса с использованием регулярных выражений
  55. // При этом отсекаем все переменные GET-запроса
  56. Match ReqMatch = Regex.Match(Request, @"^\w+\s+([^\s\?]+)[^\s]*\s+HTTP/.*|");
  57. // Если запрос не удался
  58. if (ReqMatch == Match.Empty)
  59. {
  60. // Передаем клиенту ошибку 400 - неверный запрос
  61. SendError(Client, 400);
  62. return;
  63. }
  64. // Получаем строку запроса
  65. string RequestUri = ReqMatch.Groups[1].Value;
  66. // Приводим ее к изначальному виду, преобразуя экранированные символы
  67. // Например, "%20" -> " "
  68. RequestUri = Uri.UnescapeDataString(RequestUri);
  69. // Если в строке содержится двоеточие, передадим ошибку 400
  70. // Это нужно для защиты от URL типа [url]http://example.com/file.txt[/url]
  71. if (RequestUri.IndexOf("..") >= 0)
  72. {
  73. SendError(Client, 400);
  74. return;
  75. }
  76. // Если строка запроса оканчивается на "/", то добавим к ней index.html
  77. if (RequestUri.EndsWith("/"))
  78. {
  79. RequestUri += "index.html";
  80. }
  81. string FilePath = "www/" + RequestUri;
  82. // Если в папке www не существует данного файла, посылаем ошибку 404
  83. if (!File.Exists(FilePath))
  84. {
  85. SendError(Client, 404);
  86. return;
  87. }
  88. // Получаем расширение файла из строки запроса
  89. string Extension = RequestUri.Substring(RequestUri.LastIndexOf('.'));
  90. // Тип содержимого
  91. string ContentType = "";
  92. // Пытаемся определить тип содержимого по расширению файла
  93. switch (Extension)
  94. {
  95. case ".htm":
  96. case ".html":
  97. ContentType = "text/html";
  98. break;
  99. case ".css":
  100. ContentType = "text/stylesheet";
  101. break;
  102. case ".js":
  103. ContentType = "text/javascript";
  104. break;
  105. case ".jpg":
  106. ContentType = "image/jpeg";
  107. break;
  108. case ".jpeg":
  109. case ".png":
  110. case ".gif":
  111. ContentType = "image/" + Extension.Substring(1);
  112. break;
  113. default:
  114. if (Extension.Length > 1)
  115. {
  116. ContentType = "application/" + Extension.Substring(1);
  117. }
  118. else
  119. {
  120. ContentType = "application/unknown";
  121. }
  122. break;
  123. }
  124. // Открываем файл, страхуясь на случай ошибки
  125. FileStream FS;
  126. try
  127. {
  128. FS = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
  129. }
  130. catch (Exception)
  131. {
  132. // Если случилась ошибка, посылаем клиенту ошибку 500
  133. SendError(Client, 500);
  134. return;
  135. }
  136. // Посылаем заголовки
  137. string Headers = "HTTP/1.1 200 OK\nContent-Type: " + ContentType + "\nContent-Length: " + FS.Length + "\n\n";
  138. byte[] HeadersBuffer = Encoding.ASCII.GetBytes(Headers);
  139. Client.GetStream().Write(HeadersBuffer, 0, HeadersBuffer.Length);
  140. // Пока не достигнут конец файла
  141. while (FS.Position < FS.Length)
  142. {
  143. // Читаем данные из файла
  144. Count = FS.Read(Buffer, 0, Buffer.Length);
  145. // И передаем их клиенту
  146. Client.GetStream().Write(Buffer, 0, Count);
  147. }
  148. // Закроем файл и соединение
  149. FS.Close();
  150. Client.Close();
  151. }
  152. }
  153. class Server
  154. {
  155. TcpListener Listener; // Объект, принимающий TCP-клиентов
  156. // Запуск сервера
  157. public Server(int Port)
  158. {
  159. Listener = new TcpListener(IPAddress.Any, Port); // Создаем "слушателя" для указанного порта
  160. Listener.Start(); // Запускаем его
  161. // В бесконечном цикле
  162. while (true)
  163. {
  164. // Принимаем новых клиентов. После того, как клиент был принят, он передается в новый поток (ClientThread)
  165. // с использованием пула потоков.
  166. ThreadPool.QueueUserWorkItem(new WaitCallback(ClientThread), Listener.AcceptTcpClient());
  167. /*
  168. // Принимаем нового клиента
  169. TcpClient Client = Listener.AcceptTcpClient();
  170. // Создаем поток
  171. Thread Thread = new Thread(new ParameterizedThreadStart(ClientThread));
  172. // И запускаем этот поток, передавая ему принятого клиента
  173. Thread.Start(Client);
  174. */
  175. }
  176. }
  177. static void ClientThread(Object StateInfo)
  178. {
  179. Console.WriteLine("Подключен новый клиент");
  180. // Просто создаем новый экземпляр класса Client и передаем ему приведенный к классу TcpClient объект StateInfo
  181. new Client((TcpClient)StateInfo);
  182. }
  183. // Остановка сервера
  184. ~Server()
  185. {
  186. // Если "слушатель" был создан
  187. if (Listener != null)
  188. {
  189. // Остановим его
  190. Listener.Stop();
  191. }
  192. }
  193. static void Main(string[] args)
  194. {
  195. // Определим нужное максимальное количество потоков
  196. // Пусть будет по 4 на каждый процессор
  197. int MaxThreadsCount = Environment.ProcessorCount * 4;
  198. // Установим максимальное количество рабочих потоков
  199. ThreadPool.SetMaxThreads(MaxThreadsCount, MaxThreadsCount);
  200. // Установим минимальное количество рабочих потоков
  201. ThreadPool.SetMinThreads(2, 2);
  202. // Создадим новый сервер на порту 80
  203. new Server(80);
  204. }
  205. }
  206. }

Решение задачи: «Работа с GET(POST) запросом по протоколу http»

textual
Листинг программы
  1. static private void download()
  2.         {
  3.             string url = @"http://www.cyberforum.ru/images/cyberforum_logo.png";
  4.             string filePath = @"F:\cyberforum_logo.png";
  5.             System.Net.WebClient webClient = new System.Net.WebClient();            
  6.             webClient.DownloadFile(url, filePath);        
  7.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.143 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут