获取NetworkStream中可用的数据长度

我希望能够从C#中的TCP网络流中获取可用数据的长度,以便在从网络流中读取之前设置缓冲区的大小。 有一个NetworkStream.Length属性但它尚未实现,我不想为缓冲区分配一个巨大的大小,因为它会占用太多空间。 我做这件事的唯一方法是在数据传输之前与另一个告诉大小,但这似乎有点混乱。 这对我来说最好的方法是什么。

访问Stream ,通常以小块(例如一千字节左右)读取和写入数据,或者使用像CopyTo这样的方法为您执行此操作。

这是一个使用CopyTo将流的内容复制到另一个流并使用自动resize的缓冲区从方法返回为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 } 

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

问题是,您无法确定套接字是否已读取所有数据,可能随时会有更多数据进入。 即使您以某种方式知道要预期多少数据,也可以尝试,例如,如果您有一个包含长度的包头。 可能还没有收到整个数据包。

如果您正在读取任意数据(可能是文件),您应该拥有一个合理大小的缓冲区(例如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 :)确保确实已经读取了所有数据,包括尚未通过网络传输的数据。

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

您可以先发送传入数据的长度。 例如:您要发送data = byte[16] 。 所以首先你发送16并在服务器上定义,这个长度总是2(因为16有两个字符)。 现在您知道incomingLength = 16 。 您现在可以等待lenght incomingLength数据。