Reputation: 56
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
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
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
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