【问题标题】:C# - TcpClient - Detecting end of stream?C# - TcpClient - 检测流结束?
【发布时间】:2011-06-29 15:05:01
【问题描述】:

我正在尝试将一个古老的网络摄像机连接到我的计算机,但我遇到了一个非常基本的问题 - 检测流的结尾。

我正在使用TcpClient与相机通信,我实际上可以看到它正在传输命令数据,这里没有问题。

        List<int> incoming = new List<int>();            
        TcpClient clientSocket = new TcpClient();
        clientSocket.Connect(txtHost.Text, Int32.Parse(txtPort.Text));
        NetworkStream serverStream = clientSocket.GetStream();
        serverStream.Flush();

        byte[] command = System.Text.Encoding.ASCII.GetBytes("i640*480M");
        serverStream.Write(command, 0, command.Length);

读回响应是问题开始的地方。我最初认为像以下代码这样简单的东西会起作用:

        while (serverStream.DataAvailable)
        {
            incoming.Add(serverStream.ReadByte());
        }

但它没有,所以这次我尝试了另一个版本,使用了 ReadByte()。描述指出:

从流中读取一个字节并 推进内的位置 流一个字节,如果返回 -1 在流的末尾。

所以我想我可以按照以下方式实现一些东西:

        Boolean run = true;
        int rec;
        while (run)
        {
            rec = serverStream.ReadByte();

            if (rec == -1)
            {
                run = false;
                //b = (byte)'X';
            }
            else
            {
                incoming.Add(rec);
            }

        }

不行,还是不行。我实际上可以看到数据在某个点之后进入和之后(这并不总是相同,否则我每次都可以简单地读取那么多字节)我开始将0 作为其余元素的值,但它没有在我手动停止执行之前不要停止。这是它的样子:

所以我的问题是,我在这里缺少一些基本的东西吗?如何检测流的结尾?

非常感谢,

H.

【问题讨论】:

  • 你正在从流中读取一个字节,一个字节不能是-1。
  • 这里只是在胡思乱想,但可能是流没有尽头,它只是不断传输数据,而 0 有点像是 KeepAlive 信号之类的。另一个想法可能是,0 是流的结尾。将其与您获得的其余数据进行比较,如果您只看到非零值,那么您可以假设 0 是来自相机的 EOS 信号。如果您确实看到了一些零值,只要在连续获得 4 或 8 个零时进行检测。不知道这是否有用,这就是为什么我只是发表评论。
  • 根据文档ReadByte()实际上返回一个int。
  • @MindWorX:我还没有想到 KeepAlive TBH,谢谢。可悲的是,我确实有时会在数据中得到一堆零,所以不确定我是否可以使用该方法来检测帧结束。
  • 好吧,就像下面@The Evil Greebo 建议的那样,您需要在流中找到一些模式。我建议你读一大块。也许 1kb 的数据或任何适合大多数包的数据,然后并排进行十六进制比较,看看有什么共同点,尤其是在最后,在所有零开始之前。

标签: c# sockets tcpclient networkstream


【解决方案1】:

您缺少的是您对 TCP 数据流的看法。这是一个开放的连接,就像一个开放的电话线 - 另一端的某人可能会或可能不会说话 (DataAvailable),仅仅因为他们停下来呼吸 (DataAvailable==false) 这并不意味着他们'实际上重新完成了他们当前的声明。片刻之后,他们可以再次开始交谈 (DataAvailable==true)

您需要为 TCP 之上的通信协议定义某种规则,这实际上只是一个传输层。例如,当当前图像传输完成时,相机可能会向您发送一个特殊的字符序列,因此您需要检查发送的每个字符并确定该序列是否已发送给您,然后采取适当的行动。

【讨论】:

  • 谢谢,我想我可能已经找到了一种方法,通过我用来获取帧的分辨率来实现。
【解决方案2】:

好吧,您不能在网络通信中准确地说 EOS(除非对方断开连接),通常协议本身包含一些信息来表明消息已完成(例如,有时是换行)。因此,您读取流并提供缓冲区,然后通过应用这些策略提取完整的消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-13
    • 2012-06-22
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多