WhaChi
WhaChi

Reputation: 56

Socket not reading all the bytes from server

I have a socket application that connects to a server and then recieves a buffer (size is known), but on slow networks the application does not recieve the full buffer here is my code

var bytes = new byte[65000];
Socket.Receive(bytes);

Upvotes: 0

Views: 4772

Answers (3)

Rodrigo Reis
Rodrigo Reis

Reputation: 1117

This way no need to set an initial read size, it fits to response.

public static byte[] ReceiveAll(this Socket socket)
{
    var buffer = new List<byte>();

    while (socket.Available > 0)
    {
        var currByte = new Byte[1];
        var byteCounter = socket.Receive(currByte, currByte.Length, SocketFlags.None);

        if (byteCounter.Equals(1))
        {
            buffer.Add(currByte[0]);
        }
    }

    return buffer.ToArray();
}

Upvotes: 2

Donald Jansen
Donald Jansen

Reputation: 1985

This is quite easy, you can make the necesarry changes

    private byte[] ReadBytes(int size)
    {
        //The size of the amount of bytes you want to recieve, eg 1024
        var bytes = new byte[size];
        var total = 0;
        do
        {
            var read = _connecter.Receive(bytes, total, size - total, SocketFlags.None);
            Debug.WriteLine("Client recieved {0} bytes", total);
            if (read == 0)
            {
                //If it gets here and you received 0 bytes it means that the Socket has Disconnected gracefully (without throwing exception) so you will need to handle that here
            }
            total+=read;
            //If you have sent 1024 bytes and Receive only 512 then it wil continue to recieve in the correct index thus when total is equal to 1024 you will have recieved all the bytes
        } while (total != size);
        return bytes;
    }

To simulate this I have a test console app that generated the following out put to the Debug Console (with some threading and sleeping)

Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 12 bytes
Client Reads 512 bytes
Client Recieved 100 bytes
Client Recieved 200 bytes
Client Recieved 300 bytes
Client Recieved 400 bytes
Client Recieved 500 bytes
Client Recieved 512 bytes

I had the same issue on an android application

Upvotes: 4

usr-local-ΕΨΗΕΛΩΝ
usr-local-ΕΨΗΕΛΩΝ

Reputation: 26874

The method Socket.Receive will return the number of the effective bytes that were read.

You cannot rely on the buffer size to get the full buffer read, because Receive returns if it does not receive data for a certain time. Think to 65000 as a maximum and not an effective buffer.

On a fast network you will get buffer to fill fast, but on a slow network packet delay will trigger Receive to flush itself to the buffer array.

In order to read fixed-sized buffers you may want to do:

public static byte[] ReadFixed (Socket this, int bufferSize) {
    byte[] ret = new byte[bufferSize];
    for (int read = 0; read < bufferSize; read += this.Receive(ret, read, ret.Size-read, SocketFlags.None));
    return ret;
}

The above was created as an extension method to the Socket class for more comfort of use. Code was hand-written.

Upvotes: 2

Related Questions