C# TCPListener Returns Error When Disconnect

C# TCPListener Returns Error When Disconnect
typescript
Ethan Jackson

When tcp client disconnects, tcp listener giving this error; 2 clients just sends random messages every seconds when i close 1 client, listener giving error and because of that other client giving error and closes console app.

Unhandled exception. System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host. at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count) at ConsoleApp2.Program.handle_connection(IAsyncResult result) in C:\Users\ahmet\OneDrive\Desktop\new\ConsoleApp2\Program.cs:line 67 at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) horse System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask) --- End of stack trace from previous location --- at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state) at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()

TCP LISTENER

using System; using System.Threading; using System.Collections.Concurrent; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Collections.Generic; namespace ConsoleApp2 { class Program { TcpListener server = new TcpListener(IPAddress.Any, 13000); static void Main(string[] args) { try { Program main = new Program(); main.server_start(); Console.ReadLine(); } catch (ArgumentNullException e) { Console.WriteLine("ArgumentNullException: {0}", e); } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); } } private void server_start() { try { server.Start(); } catch (ArgumentNullException e) { Console.WriteLine("ArgumentNullException: {0}", e); } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); } Console.WriteLine("Sunucu Başlatıldı. Bağlantı Bekleniyor..."); accept_connection(); } private void accept_connection() { try { server.BeginAcceptTcpClient(handle_connection, server); } catch (ArgumentNullException e) { Console.WriteLine("ArgumentNullException: {0}", e); } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); } } private void handle_connection(IAsyncResult result) { try { Console.WriteLine("Bağlandı..."); accept_connection(); TcpClient client = server.EndAcceptTcpClient(result); NetworkStream stream = client.GetStream(); Byte[] bytes = new Byte[256]; String data = null; int i; while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) { data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); Console.WriteLine("{0}", data); } } catch (ArgumentNullException e) { Console.WriteLine("ArgumentNullException: {0}", e); } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); } } } }

TCP CLİENT

using System; using System.Threading; using System.Collections.Concurrent; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Collections.Generic; namespace ConsoleApp2 { class Program { static TcpClient client = new TcpClient("127.0.0.1",13000); static List\<string\> mesajlar = new List\<string\>(); public static readonly object locker = new object(); static void Main() { ThreadPool.QueueUserWorkItem(MesajlariAta); Thread.Sleep(100); ThreadPool.QueueUserWorkItem(MesajGonder); Console.ReadLine(); } static void MesajlariAta(object state) { lock (locker) { mesajlar.Add("Java"); mesajlar.Add("C"); mesajlar.Add("C++"); mesajlar.Add("C#"); mesajlar.Add("Python"); mesajlar.Add("HTML"); mesajlar.Add("CSS"); mesajlar.Add("PHP"); mesajlar.Add("MERHABA"); } } static void MesajGonder(object state) { while (true) { var random = new Random(); string message = mesajlar[random.Next(mesajlar.Count)]; Byte[] data = System.Text.Encoding.ASCII.GetBytes(message); NetworkStream stream = client.GetStream(); stream.Write(data, 0, data.Length); Console.WriteLine("Mesaj Gönderildi"); Thread.Sleep(1000); } } } }

tried return false but it says BeginAcceptTcpClient() waiting void

Answer

Solution:

You need to wrap the reading logic inside a try-catch block and handle disconnections gracefully. Also, make sure to close the client socket in the finally block to release the connection.


handle_connection Method:

private void handle_connection(IAsyncResult result) { TcpClient client = null; try { Console.WriteLine("Client connected..."); accept_connection(); // Keep accepting new connections client = server.EndAcceptTcpClient(result); NetworkStream stream = client.GetStream(); Byte[] bytes = new Byte[256]; String data = null; int i; while (true) { try { i = stream.Read(bytes, 0, bytes.Length); if (i == 0) break; // Client disconnected gracefully data = Encoding.ASCII.GetString(bytes, 0, i); Console.WriteLine("Received: {0}", data); } catch (IOException ioEx) { Console.WriteLine("Client disconnected: " + ioEx.Message); break; } catch (Exception ex) { Console.WriteLine("Read error: " + ex.Message); break; } } } catch (Exception ex) { Console.WriteLine("Connection error: " + ex.Message); } finally { client?.Close(); // Always close client socket } }

Other Tips

1. Don’t create new Random() inside the loop:

In your client code, you're doing:

var random = new Random(); // every second!

Instead, define it once globally:

static Random random = new Random();

2. You don’t need locking for the message list:

If you're only adding messages once and not modifying the list after that, you can remove the locker logic.


Optional: Use Task for Multiple Clients

If you want better performance with multiple clients, modify the connection handler like this:

private void accept_connection() { server.BeginAcceptTcpClient(result => { TcpClient client = server.EndAcceptTcpClient(result); Task.Run(() => handle_client(client)); accept_connection(); // Keep listening for more }, null); }

Then make handle_client(TcpClient client) a method with the read logic.

Related Articles