McMannus
McMannus

Reputation: 279

TcpClient established, but TcpClient.getStream() fails

My Client class for synchronous message exchange:

public class AsClient
{
    private TcpClient connection;

    public AsClient(int serverPort, String ip)
    {
        connection = new TcpClient(ip, port);
    }

    public AsMessage sendMessage(AsMessage message)
    {
        System.Diagnostics.Debug.WriteLine("Connected: " + connection.Connected);
        NetworkStream ns = connection.GetStream();

        StreamReader reader = new StreamReader(ns);
        StreamWriter writer = new StreamWriter(ns);

        // Send Message:
        String msgToSendEncoded = message.encode();
        writer.WriteLine(msgToSendEncoded);
        writer.WriteLine("\n"); // each message is terminated by a paragraph
        writer.Flush();

        // Receive Message:
        String msgReceivedRaw = reader.ReadLine();
        AsMessage response = AsMessage.decode(msgReceivedRaw);

        reader.Dispose();
        writer.Dispose();

        ns.Close();

        return response;
    }
}

If I debug this application, the first message sent and response received works perfectly well, but as soon as I want to send the second message, TcpClient.getStream() fails with the InvalidOperationException, which states that the connection is not established anymore.

The problem is that I am not actively closing the connection anywhere. If I put connection.Connect(host,port) before calling getStream(), it fails with the exception that the socket is still connected, even though connection.Connected is false.

Any ideas to solve this issue?

Upvotes: 1

Views: 3803

Answers (2)

Guillermo
Guillermo

Reputation: 82

I'm running into the same problem with this piece of code that replicates follows the steps in the MS documentation for GetStream(): https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.getstream?view=netframework-4.8

    public void Send(String message)
    {
        try
        {
            // Translate the passed message into ASCII and store it as a Byte array.
            Byte[] data = Encoding.ASCII.GetBytes(message);

            // Get a client stream for reading and writing.
            NetworkStream stream = Client.GetStream();

            stream.Write(data, 0, data.Length);

             stream.Close(); // this also closses the connection the server!
        }
        catch (Exception e)
        {
            LogException(e);
        }

    }

What we see on the server side is that: 1) The connection is established. 2) The message never arrives. 3) when the stream.Close() statement executes, the server reports that the client closed the connection. Inspecting the properties of stream I can see that streams OWNS the socket. So, wen it closes it must also close its socket. How come???

Upvotes: 0

butterbox
butterbox

Reputation: 452

As I have experience Dispose close the underlying stream.

So you close the connection on the Dispose.

Upvotes: 1

Related Questions