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.