TcpClient - existing connection was forcibly closed by the remote host

Information

I am developing a web http server in C # and decided to add a remote console function. The console can be used from anywhere and uses TcpListener (web server) and 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 starts in a separate thread for both the web server thread and the main console application.

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();
    }
}

Problem

I can send one command to the server with a successful return. However, when I try to send another command, the server gives the following error:

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 that this is not a problem with the firewall or administrator, as I can successfully send one command. Only when sending the second command does it give this error.

, : The remote console and server communication and error reporting.

EDIT: , , , , for. , , , :). , , .

+4
3

, .

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

, , , . , . , .

+4

, , , , , .

, , , , (networkStream).

networkstream.Read(mybuffer, 0, mybuffer.length);

, :

do
{
 byte[] buff = new byte[1];
 networkstream.Read(buff, 0, 1);
 myreceivedbuff.Add(buff);
} while (networkstream.DataAvailable)

,

do
{
 byte[] buff = new byte[1];
 try
 {
  networkstream.Read(buff, 0, 1);
 }
 catch(exception ex)
 {
  throw new exception("The dam client disconnected in the middle of a transaction.");
 }
 myreceivedbuff.Add(buff);
} while (networksteam.DataAvailable)

, , . , CLIENT, .

, vs, , , .

, -.

+4

I had the same solution. this usually happens if the client is disconnected. The solution from Alex RG does not work, unfortunately. you will get one more exception. The best solutions are described here by Microsoft.

you need to check with CanRead

TcpClient tcpClient = new TcpClient ();

// Uses the GetStream public method to return the NetworkStream.
NetworkStream netStream = tcpClient.GetStream ();

if (netStream.CanRead)
{
    // Reads NetworkStream into a byte buffer.
    byte[] bytes = new byte[tcpClient.ReceiveBufferSize];

    // Read can return anything from 0 to numBytesToRead. 
    // This method blocks until at least one byte is read.
    netStream.Read (bytes, 0, (int)tcpClient.ReceiveBufferSize);

    // Returns the data received from the host to the console.
    string returndata = Encoding.UTF8.GetString (bytes);

    Console.WriteLine ("This is what the host returned to you: " + returndata);

}
else
{
    Console.WriteLine ("You cannot read data from this stream.");
    tcpClient.Close ();

    // Closing the tcpClient instance does not close the network stream.
    netStream.Close ();
    return;
}
0
source

Source: https://habr.com/ru/post/1548550/


All Articles