假设我事先了解了有效负载字节。接收所有字节的正确方法是什么?目前,我正在做这样的事情
byte[] buffer = new byte[payloadLength];
socket.Receive(buffer, buffer.Length, SocketFlags.None);
但是,我认为如果有效负载很大并且Receive
可能无法一次性接收整个数据。所以我打算做这样的事情
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);
哪一个更正确?或者你的家伙有更好的主意吗?
答案 0 :(得分:2)
绝对某些变体,如第二个。忽略Receive
的返回值是SO上最常见的初学者错误之一,因为合同保证(如果你不要求0字节){ {1}}返回的是它将读取至少一个字节。它无法保证它会尝试读取您要求的字节数。 1
任何消息框架(例如此处显示固定大小的消息)都取决于你在TCP字节流上实现。
1 即使接收尺寸相对较小,也无法保证。因此,如果你知道你的消息有多大,因为你首先发送长度(另一种常见的消息框架方式),你需要循环甚至获得构成消息的2/4/8字节长度短,整数或长。
答案 1 :(得分:1)
在实践中,第一种选择通常有效。但是你不能保证它,所以如果你关心的是一个严肃的程序,那么采取第二种方法。
当然,如果您切换到ReceiveAsync,如果您有高性能需求,那么您需要采用第二种方法。