C# client server application, BinaryReader throws an exception

3.5k views Asked by At

I've got task to make a server application, which checks if any file on the server (which name must be sent by the client) exists and if it exists to give back a response (message - "This file exists."). I've got problem with this. The server is making the right thing but when I try to use my BinaryReader to read the response it gives me back this exception:

Unable to read beyond the end of the stream

Here is some code from the client:

    private void OnRequest()
    {
        try
        {
            IPEndPoint serverIp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 55555);
            TcpClient client = new TcpClient();
            client.Connect(serverIp);
            if (client.Connected)
            {
                AddLog("Connected!");

                writer = new BinaryWriter(client.GetStream());

                writer.Write("request");
                GetFileText();
                writer.Write(fileText);
                writer.Flush();

                AddServerResponse(GetResponse(client.Client));

                writer.Close();
                client.Close();
                AddLog("Disconnected!");
            }

        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

And that's the GetResponse method:

    private string GetResponse(Socket server)
    {
        NetworkStream stream = new NetworkStream(server);
        reader = new BinaryReader(stream);
        string message;
        do
        {
            message = reader.ReadString();
        }
        while (message != null);
        reader.Close();
        return message;
    }

And here how I'm sending data to the client:

    private void SendDataToClient(string data, Socket client)
    {
        if (client != null && client.Connected)
        {
            NetworkStream stream = new NetworkStream(client);
            BinaryWriter writer = new BinaryWriter(stream);
            writer.Write(data);
            writer.Flush();
            writer.Close();
            stream.Close();
        }
    }

Could you help me, please?

3

There are 3 answers

0
BlueMonkMN On BEST ANSWER

After you read the string, you detect that message != null and so the loop runs again. But the server has not written anything else to the stream, so when you try to read the next string, there's nothing to read. Every ReadString first reads a string length and then the string data (see http://msdn.microsoft.com/en-us/library/system.io.binaryreader.readstring.aspx). The server hasn't even made a string length available to read, so you get an error. I think that's what's happening. You need some indicator of how long the stream is or when you've reached the end.

1
Jeff Yates On

I would expect that the stream hasn't provided the completely binary object graph and so the BinaryReader is trying to deserialize a partial object.

0
jgauffin On

TCP is a stream oriented protocol, not a message oriented protocol. This means that everything is guranteed to arrive in the correct order and than all or nothing is received. However, it do not mean that everything will arrive with the same read.

It's up to you to make sure that everything have been received properly before you attempt to read it.

Google some on NetworkStream and see how others use it in server applications. You normally send a header and than the data.