MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Без причины закрывается консольное приложение с сервером TcpListener на Windows 7"
Answer 939417
Во-первых, добавьте обработку исключений. Сейчас у вас нечему вызвать сообщение об ошибке (ну и вообще, сервер должен не выводить сообщение, а заносить запись в лог). Во-вторых, неплохо бы провести рефакторинг:
Классу Client не нужен конструктор, так как у него нет состояния.
Классу Server не нужен финализатор, так как у него нет нормальной реализации IDisposable, да и его время жизни все равно совпадает со временем жизни приложения.
У класса Server конструктор уходит в бесконечный цикл. Это странный способ, лучше вынести цикл в отдельный метод.
Client.GetStream().Read
- потенциальная утечка неуправляемых ресурсов. Объекты IDisposable нужно всегда сохранять в переменную и оборачивать их использование в using. Никогда не знаешь, отработает ли финализатор по нормальному.В итоге получаем такой код:
using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using System.Collections.Generic; using System.Text; namespace ConsoleApp1 { class Server { TcpListener Listener; public Server(int Port) { Listener = new TcpListener(IPAddress.Any, Port); } public void Run() { Listener.Start(); Client.ReplyClient(Listener.AcceptTcpClient()); while (true) { TcpClient Client = Listener.AcceptTcpClient(); Thread Thread = new Thread(new ParameterizedThreadStart(ClientThread)); Thread.Start(Client); } } static void Main(string[] args) { try { var Server = new Server(80); Server.Run(); } catch (Exception ex) { //запись в лог (можно заменить на Console.WriteLine на время отладки) File.WriteAllText( "server.log", DateTime.Now.ToString() + Environment.NewLine + ex.ToString() + Environment.NewLine ); } } static void ClientThread(Object StateInfo) { try { Client.ReplyClient((TcpClient)StateInfo); } catch (Exception ex) { //запись в лог (можно заменить на Console.WriteLine на время отладки) File.WriteAllText( "server.log", DateTime.Now.ToString() + Environment.NewLine + ex.ToString() + Environment.NewLine ); } } } class Client { public static void ReplyClient(TcpClient Client) { string Request = ""; byte[] Buffer = new byte[1024]; int Count; Stream stream; try { while (true) { stream = Client.GetStream(); using (stream) { Count = stream.Read(Buffer, 0, Buffer.Length); if (Count <= 0) break; } Request += Encoding.ASCII.GetString(Buffer, 0, Count); if (Request.IndexOf("\r\n\r\n") >= 0 || Request.Length > 4096) { break; } } string Html = Моя_Процедура_Над_Телом_запроса(Request); string Str = "HTTP/1.1 200 OK\nContent-type: text/html\nContent-Length:" + Html.Length.ToString() + "\n\n" + Html; byte[] Buff = Encoding.ASCII.GetBytes(Str); stream = Client.GetStream(); using (stream) { stream.Write(Buff, 0, Buff.Length); } } finally { Client.Close(); } } } }
Вообще, если нужен HTTP сервер, можно использовать HttpListener, это проще.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.