Kazoom
Kazoom

Reputation: 5849

Strange behaviour of networkstream.read() in C#

When i write to a network stream two seperate byte array, i sometimes dont get the first byte array. Why is that?

For eg This fails, the header is not received, sometimes by Read() on other side

            byte[] header = msg.getByteHeader();
            byte[] data = msg.getByteData();
            clientStream.Write(header, 0, header.Length);
            clientStream.Write(data, 0, data.Length);
            clientStream.Flush();

however this succeeds

                NetworkStream clientStream = tcpClient.GetStream();
                byte[] header = msg.getByteHeader();
                byte[] data = msg.getByteData();
                int pos = 0;
                Array.Copy(header, 0, message, pos, header.Length);
                pos += header.Length;
                Array.Copy(data, 0, message, pos, data.Length);
                clientStream.Write(message, 0, message.Length);

This is how my Read() looks

           try
            {
                //blocks until a client sends a message
                bytesRead = clientStream.Read(message, 0, 4);
                //string stringData = Encoding.ASCII.GetString(message, 0, bytesRead);
                len = BitConverter.ToInt32(message, 0);
                //MessageBox.Show(len.ToString());
                bytesRead = clientStream.Read(message, 0, 5 + len);

            }

Upvotes: 1

Views: 1679

Answers (3)

sipsorcery
sipsorcery

Reputation: 30699

You could troubleshoot it by commenting out the second Write and see if your server is sent any data.

Your reading mechanism does look very very fragile and I'd agree with Simon Fox that it does not look like it's correct. Why is the second read asking for len + 5 bytes? I would have thought it would only be len bytes since the first read was for the 4 header bytes.

If I was you I'd add a delimiter to the start of your header transmission. That will allow your receivers to scan for that to determine the start of a packet. With TCP you will often get fragemented transmissions or multiple transmissions bundled into the same packet. Things will go wrong once you deploy to real networks such as the internet if you are always relying on getting exactly the number of bytes you request.

Either that or switch to UDP where you can rely on having one transmission per packet.

Upvotes: 1

Paul Sasik
Paul Sasik

Reputation: 81429

i believe this is a timing issue. There's a lag between when you first open socket communication and when you can read the first data from the buffer. It's not instantaneous. You can query the DataAvailable boolean status of network stream before attempting to read. If there's no DataAvailable, Sleep the thread for say 100 ms and then try reading again.

Upvotes: 1

Simon Fox
Simon Fox

Reputation: 10561

Aren't you overwritting what you read in the first call to read with the second call? The second argument to Read is the offset at which to start storing the data read, both calls use 0 so the second overwrites the first...

Upvotes: 0

Related Questions