2

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

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

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

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

编辑:

这对我不起作用:

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

2 回答 2

5

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

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

  1. 让发送者将长度(int 或 long)作为流的前 4(或 8)个字节发送。接收器读取此长度,然后继续读取流,直到读取到那么多字节。
  2. 同意“流结束”标记。这可以采取多种形式。例如,对于仅包含 ASCII 字符串的简单流,您可以同意字节值 255 表示字符串结束。或者您可以使用 ASCII EOT 字符。对于面向记录的字符串,记录的第一个字节可能是记录类型,记录类型 0xFF 可能表示“记录结束”。

换句话说,网络流无法知道何时结束。不像文件流可以。您必须在数据中编码流长度或流标记的结尾。

更新

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

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

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

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

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

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

于 2013-08-16T15:31:48.523 回答
2

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

利用

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

如果您真的需要流的长度,您可以将其内容复制到 aMemoryStream并读取其.Length属性:

MemoryStream s = new MemoryStream();
myNetworkStream.CopyTo(s);
int length = s.Length;
于 2013-08-16T14:43:56.223 回答