TcpClient - An existing connection was forcibly closed by the remote host

c#, tcpclient, tcplistener

Solution

It seems that your client closes the connection after one message.

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
client.Close();
return responseData; //returns what server writes

If you want to persist the connection you should have a loop on the client similar to the one you have on the server. If you want to establish a new connection every time you should close the stream gracefully on the server and not have a loop like this. You will still need to loop in case the message is longer or you need to specify max length for the command.

Problem

The Info I have been developing a web http server in c# and decided to add a remote console feature. The console can be used from any location and uses a TcpListener (web server) and a TcpClient (remote console) to send commands and functions through. The Code This is what my server looks like: ``` TcpListener consoleListener = new TcpListener(consolePort); consoleListener.Start(); byte[] bytes = new Byte[256]; string data = null; while (true) { TcpClient client = consoleListener.AcceptTcpClient(); data = null; byte[] msg = { 0 }; int i; while ((i = client.GetStream().Read(bytes, 0, bytes.Length)) != 0) { data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); if (data == "shutdown") { //Server shutdown logic. } //Other commands here... else { msg = Encoding.ASCII.GetBytes("Invalid command. Type 'help' or '?' to get a list of commands."); } client.GetStream().Write(msg, 0, msg.Length); //sends return message to console } client.Close(); //closes connection between client and server after EVERY command. Connection is reopened when a new command is sent. } ``` Note - The server is run on a separate thread to both the webserver and main console application thread. This is my client: ``` public static string Communicate(string text) { try { TcpClient client = new TcpClient(ip, port); //initializes tcpclient (ip and port are correct) byte[] data = System.Text.Encoding.ASCII.GetBytes(text); //converts text to bytes for stream writing NetworkStream stream = client.GetStream(); stream.Write(data, 0, data.Length); Console.WriteLine("Sent data: " + text); data = new Byte[256]; string responseData = String.Empty; //initializes responsData string Int32 bytes = stream.Read(data, 0, data.Length); responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); client.Close(); return responseData; //returns what server writes } catch (Exception ex) { return "An error occured\n" + ex.ToString(); } } ``` The Problem I can send one command to the server with a successful return. However, when I try and send another command, the server throws the error below: ``` 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: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) at ---.Server.ConsoleListener() in X:\Users\---\Documents\Visual Studio 2013\Projects\---\---\Program.cs:line x ``` I know it is not firewall or administrator elevation problems as I can send one command through successfully. It is only on the second command sent that it throws this error. Here is a screenshot describing the problem: EDIT: By doing a little research, I found that the problem is most likely a result of a small error in my for loop. However, I do not know any way of fixing this as I do not know the exact problem :). Please help me identify it so I can fix it. Thanks again

Original source