C# 这个代码能确保我从一个套接字读取所有我想要的吗?

C# 这个代码能确保我从一个套接字读取所有我想要的吗?,c#,sockets,C#,Sockets,执行Socket.Receive(byte[])将从缓冲区中获取字节,但如果预期的数据相当大,则所有字节可能尚未在缓冲区中,这将为我提供一个仅部分填充的字节数组。这段代码能确保我读入所有我想要的东西吗 sock.Receive(message_byte, message_byte.Length, SocketFlags.None); 其中message_byte已经声明为我期望的数据的确切大小。我这样做对吗?此处理的任何内容都不会大于~10兆,因此在声明字节数组时不太可能出现OutOfMemo

执行Socket.Receive(byte[])将从缓冲区中获取字节,但如果预期的数据相当大,则所有字节可能尚未在缓冲区中,这将为我提供一个仅部分填充的字节数组。这段代码能确保我读入所有我想要的东西吗

sock.Receive(message_byte, message_byte.Length, SocketFlags.None);

其中message_byte已经声明为我期望的数据的确切大小。我这样做对吗?此处理的任何内容都不会大于~10兆,因此在声明字节数组时不太可能出现OutOfMemory异常。

否,
Receive
返回接收的字节数。你应该妥善处理这件事

var needBytes = message_byte.Length;
var receivedBytes;
var totalReceivedBytes = 0;
do
{
    receivedBytes = sock.Receive(message_byte, totalReceivedBytes, needBytes, SocketFlags.None);
    needBytes -= receivedBytes;
    totalReceivedBytes += receivedBytes;
} while (needBytes > 0 && receivedBytes > 0)

否,代码将无法确保收到完整的消息。您应该检查接收的字节数并循环,直到收到完整的消息

请记住,如果从客户端顺序发送多条消息,您也可能开始接收下一条消息的一部分。例如,如果您的消息是100字节,第一次调用可能返回60字节,您将循环并再次读取,得到58字节,这意味着您现在已收到第一条消息的100字节和下一条消息的前18字节,因此您也需要正确处理此问题

注意:您不能对接收字节时如何分割字节做出任何假设。它只是一个流,操作系统在开始接收数据时会通知您,没有消息帧的概念,这完全由您来管理


希望有意义。

您的编辑增加了很多帮助,谢谢。我没有注意到receive方法的一个重载有一个偏移量值,这很有帮助。在while语句中,为什么需要检查receivedBytes>0,为什么不能只检查needBytes?@cost,因为“如果远程主机使用Shutdown方法关闭套接字连接,并且所有可用数据都已收到,那么Receive方法将立即完成并返回零字节。”谢谢,很高兴知道这些意外的问题。想想你刚才说的为什么会有receivedBytes>0,如果服务器崩溃,这不会迫使无限循环吗?