Если клиент завершает работу, сервер продолжает выполнять метод clientlistener. Как решить эту проблему?
Сервер запускается, и клиент подключается, он многопоточен, и главное-транслировать сообщение, чтобы оно попало на сервер. Однако, когда а клиент отключается(принудительно закрывается), он все еще пытается запустить метод ClientListener(подчеркнуто)
СЕРВЕРНЫЙ КОД:
using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.IO; using System.Text; using System.Threading; namespace Server { class Program { private static TcpListener tcpListener; private static List<TcpClient> tcpClientsList = new List<TcpClient>(); private static Boolean wroteshutdownonce = false; static void Main(string[] args) { Console.Write("Please input, what the port should be: "); int port = Convert.ToInt32(Console.ReadLine()); tcpListener = new TcpListener(IPAddress.Any, port); tcpListener.Start(); Console.Write(time()); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("Server started"); while (true) { TcpClient tcpClient = tcpListener.AcceptTcpClient(); tcpClientsList.Add(tcpClient); Thread thread = new Thread(ClientListener); thread.Start(tcpClient); wroteshutdownonce = false; } } public static void ClientListener(object obj) { TcpClient tcpClient = (TcpClient)obj; StreamReader reader = new StreamReader(tcpClient.GetStream()); Console.Write(time()); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("Client connected"); while (true) { //try //{ string message = reader.ReadLine(); BroadCast(message, tcpClient); Console.Write(time()); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(message); //} catch //{ /*if (wroteshutdownonce == false) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.WriteLine("One Client has been shut down!!"); Console.ForegroundColor = ConsoleColor.White; tcpClient.Close(); wroteshutdownonce = true; }*/ //} } } public static void BroadCast(string msg, TcpClient excludeClient) { foreach (TcpClient client in tcpClientsList) { if (client != excludeClient) { StreamWriter sWriter = new StreamWriter(client.GetStream()); sWriter.WriteLine(msg); sWriter.Flush(); } } } static string time() { String datetime = Convert.ToString(DateTime.Now); string[] splittedTime = datetime.Split(' '); datetime = "[" + splittedTime[0] + splittedTime[1] + splittedTime[2] + " " + splittedTime[3] + "] "; Console.ForegroundColor = ConsoleColor.Green; return datetime; } } }
КЛИЕНТСКИЙ КОД:
using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.IO; using System.Text; using System.Threading; namespace BroadcastClient { class Program { static void Main(string[] args) { Console.Write("Type in your username: "); String username = Console.ReadLine(); try { TcpClient tcpClient = new TcpClient("127.0.0.1", 5001); Console.WriteLine("Connected to server."); Console.WriteLine(""); Thread thread = new Thread(Read); thread.Start(tcpClient); StreamWriter sWriter = new StreamWriter(tcpClient.GetStream()); while (true) { if (tcpClient.Connected) { string input = Console.ReadLine(); sWriter.WriteLine(username+";" + input); sWriter.Flush(); } } } catch (Exception e) { Console.Write(e.Message); } Console.ReadKey(); } static void Read(object obj) { TcpClient tcpClient = (TcpClient)obj; StreamReader sReader = new StreamReader(tcpClient.GetStream()); while (true) { try { string message = sReader.ReadLine(); Console.WriteLine(message); } catch (Exception e) { Console.WriteLine(e.Message); break; } } } } }
Что я уже пробовал:
Он продолжает сбрасывать следующую ошибку:
Системы.ИО.Исключение IOException
HRESULT = 0x80131620
Сообщение = не удается прочитать транспортное соединение: существующее соединение было принудительно закрыто удаленным хостом.
исходная система
Трассировка стека:
в System.Net.Sockets.Сетевой поток.Read (Byte [] buffer, Int32 offset, Int32 size)
в System.IO.StreamReader.ReadBuffer ()
в системе.ИО.Что streamreader.С readline ()
на сервере.Программа.ClientListener (Object obj) в C: \ Users \ username \ Desktop \ C # Broadcasting \ BroadcastServer \ Program.cs: строка 52
в системе.Нарезание резьбы.ThreadHelper.ThreadStart_Context (состояние объекта)
в системе.Нарезание резьбы.Параллельном режиме.RunInternal (параллельном режиме параллельном режиме, ContextCallback обратного вызова, состояние объекта, логическое preserveSyncCtx)
в системе.Нарезание резьбы.Параллельном режиме.Выполнения (в параллельном режиме параллельном режиме, ContextCallback обратного вызова, состояние объекта, логическое preserveSyncCtx)
в системе.Нарезание резьбы.Параллельном режиме.Выполнения (в параллельном режиме параллельном режиме, ContextCallback обратного вызова, состояние объекта)
в системе.Нарезание резьбы.ThreadHelper.ThreadStart (Object obj)
Внутреннее Исключение 1:
SocketException: существующее соединение было принудительно закрыто удаленным хостом
ПЫТАТЬСЯ:
- перерыв; метод
- создать переменную wroteshutdownonce, поэтому он не будет бегать на объект TcpClient.Close(); повторите команду.
- объект TcpClient.Закрывать();
Спасибо Вам за помощь!