Reputation: 11181
Assuming that I know the payload bytes before hand. What is the correct way to receive all the bytes? Currently, I am doing something like this
byte[] buffer = new byte[payloadLength];
socket.Receive(buffer, buffer.Length, SocketFlags.None);
But then, I thought that what if the payload is big and Receive
might not be able to receive the whole data in one go. So I was planning to do something like this
byte[] buffer = new byte[payloadLength];
int remained = payloadLength;
int size = 0;
do {
size = socket.Receive(buffer, payloadLength - remained, remained, SocketFlags.None);
remained -= size;
} while (remained > 0 && size > 0);
Which one is more correct? Or do you guy have any better idea?
Upvotes: 0
Views: 161
Reputation: 1327
In practice the first option usually works. However you cannot guarantee it, so if it's a serious program that you care about then take the 2nd approach.
Certainly if you switched to ReceiveAsync, which you should if you have high performance needs, you would need to take the 2nd approach.
Upvotes: 1
Reputation: 239794
Definitely some variant like the second. Ignoring the return value from Receive
is one of the most common beginner bugs found on SO, because all that the contract guarantees (if you don't ask for 0 bytes) when Receive
returns is that it will have read at least one byte. It makes no guarantee that it will try to read as many bytes as you've asked for.1
Any message framing (such as here with fixed size messages, apparently) is up to you to implement atop TCPs streams of bytes.
1Even for relatively small receive sizes, there's no guarantee. So if you know how big your message is going to be because you're sending the length first (another common means of message framing), you need to loop even to get the 2/4/8 bytes that make up the message length short, int or long.
Upvotes: 2