如何判断Stream何时结束?

时间:2013-08-16 14:35:38

标签: c# tcp stream

如何在不使用BinaryWriter / Reader的情况下将TCP流的大小嵌入或告知接收器?

必须有一种快速的方法让它知道它是否已经到达终点,当然除了连接之外。

tcp.GetStream().Write(ms.GetBuffer(), 0, (int)ms.Length);

我这样发送,但接收是困难的部分。

编辑:

这对我不起作用:

                while (tt1.GetStream().DataAvailable)
                {
                    su = Image.FromStream(tt1.GetStream());
                }

2 个答案:

答案 0 :(得分:3)

不,当你到达网络流的末尾时,没有办法(快或慢)。 DataAvailable会告诉您数据当前是否可用,但无法告诉您是否有更多数据可能会在流中传输。

我知道有两种可靠的方法可以确定您是否已到达网络流的末尾:

  1. 让发送方发送长度(int或long)作为流的前4个(或8个)字节。接收器读取此长度,然后继续读取流,直到读取多个字节为止。
  2. 同意“流结束”标记。这可以采取多种形式。例如,对于仅包含ASCII字符串的简单流,您可以同意字节值255表示字符串结束。或者您可以使用ASCII EOT字符。对于面向记录的字符串,记录的第一个字节可以是记录类型,记录类型0xFF可能表示“记录结束。”
  3. 换句话说,网络流无法知道它何时结束。不像文件流可以。您必须在数据中对流长度或流末尾标记进行编码。

    更新

    System.Drawing.Image.FromStream的文档说:

      

    如果使用相同的流连续调用此方法,则流将重置为零。

    因此,您无法使用该方法从同一个流中读取多个图像。

    我怀疑你需要做的是改变你的数据,使其结构如下:

    length | data for image 1 | length | data for image 2 | 0
    

    然后你将读取长度,将多个字节读入字节数组,并从该字节数组创建图像(可能通过在其周围包裹内存流),然后读取下一个长度,下一个字节块等等,直到你读取长度为0,表示流的结束。

答案 1 :(得分:2)

您可以使用接收器中的.DataAvailable属性来确定要读取的流中是否仍有可用数据,但未实现Length属性本身。

使用

do {
    ...
    myNetworkStream.Read(buffer, 0, someSizeToCopyEachLoop)
}
while(myNetworkStream.DataAvailable);

如果您确实需要流的长度,可以将其内容复制到MemoryStream并阅读该.Length属性:

MemoryStream s = new MemoryStream();
myNetworkStream.CopyTo(s);
int length = s.Length;