获取 NetworkStream 中可用数据的长度

问题描述 投票:0回答:5

我希望能够从 C# 中的 TCP 网络流获取可用数据的长度,以便在从网络流读取之前设置缓冲区的大小。有一个

NetworkStream.Length
属性,但尚未实现,我不想为缓冲区分配巨大的大小,因为它会占用太多空间。我认为这样做的唯一方法是在数据传输之前告诉另一个数据的大小,但这似乎有点混乱。对我来说最好的方法是什么。

c# .net sockets tcp networkstream
5个回答
17
投票

访问

Stream
s 时,您通常会以小块(例如 KB 左右)读写数据,或者使用像
CopyTo
这样的方法来为您完成此操作。

这是一个使用

CopyTo
将一个流的内容复制到另一个流并使用自动调整大小的缓冲区将其作为
byte[]
从方法返回的示例。

using (MemoryStream ms = new MemoryStream())
{
    networkStream.CopyTo(ms);
    return ms.ToArray();
}

这是以相同方式读取数据的代码,但更手动,这可能更适合您使用,具体取决于您对数据执行的操作:

byte[] buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead;
while((bytesRead = networkStream.Read(buffer, 0, buffer.Length)) > 0)
{
    //do something with data in buffer, up to the size indicated by bytesRead
}

(这些代码片段的基础来自从流中读取数据的最有效方法


3
投票

网络流没有固有的长度。您必须从另一端发送要遵循的数据长度,或者将所有传入数据读取到不同的流中,您可以在其中访问长度信息。


2
投票

问题是,您还不能真正确定套接字已读取所有数据,更多数据可能随时进入。即使您以某种方式确实知道需要多少数据,例如您有一个包含长度的包标头,这也是一种尝试。整个数据包可能尚未收到。

如果您正在读取任意数据(例如文件),您应该有一个合理大小的缓冲区(例如 1k-10k 或任何您认为最适合您的场景的缓冲区),然后将数据写入文件中流。

var buffer = byte[1000];
var readBytes = 0;
using(var netstream = GetTheStreamSomhow()){
    using(var fileStream = (GetFileStreamSomeHow())){
        while(netstream.Socket.Connected) //determine if there is more data, here we read until the socket is closed
        {
            readBytes = netstream.Read(buffer,0,buffer.Length);
            fileStrem.Write(buffer,0,buffer.Length);
        }
    }
}

或者像 Tim 建议的那样使用

CopyTo
:) 只需确保所有数据确实已被读取,包括尚未通过网络传输的数据。


0
投票

您可以先发送传入数据的长度。 例如: 您有

data = byte[16]
要发送。因此,首先您发送 16 并在服务器上定义,该长度始终为 2(因为 16 有两个字符)。现在你知道了
incomingLength = 16
。您现在可以等待
incomingLength
长度的数据。


0
投票
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, pars); // pars - some array of standart (not user) types
byte[] buff = BitConverter.GetBytes((Int32)ms.Length);
socket.Send(buff);
socket.Receive(buff);  // read for server answer
if (BitConverter.ToInt32(buff, 0) == 200)
{
    NetworkStream ns = new NetworkStream(socket);
    ms.CopyTo(ns);
}
© www.soinside.com 2019 - 2024. All rights reserved.