【问题标题】:Does reading from a telnet stream into a large byte array wait until the byte array is full?从 telnet 流读取到大字节数组是否要等到字节数组已满?
【发布时间】:2010-10-23 02:18:39
【问题描述】:

通过阅读这里的一些问题和答案,似乎 telnet 流从未真正关闭。使用 DataAvailable() 不会返回。

我继承了一些需要很长时间才能完成的代码,我们认为问题出在 telnet 服务器上。但是,有一个字节[32757],代码试图在其中存储 telnet 服务器的响应。

类似于以下内容:

Byte byteArray[] = new Byte[32757];
TcpClient sock = new TcpClient();
sock.GetStream().read(byteArray, 0 byteArray.length);

如果没有 32757 字节或更多字节,我假设此代码会等待,直到发送足够的空数据包来构成字节数组的大小。这是正确的吗?

有没有办法检查 telnet 服务器是否已完成发送它想要发送的所有内容? telnet 会话的每个“页面”中没有可见的终止字符或字符串。

我正在考虑纠正此代码的一种方法是一次读取几个字节,将其添加到字符串中,检查字符串中是否存在终止字符或字符集,如果找到则返回。否则,读取更多字节,将其添加到字符串中,然后再次检查。

建议?

【问题讨论】:

    标签: c# stream bytearray telnet


    【解决方案1】:

    除了 Jon Skeets 的解释一个小提示:

    由于 telnet 是基于文本(行)的协议,读取 byte[] 意味着您必须重新组合文本。使用 TextReader 会更好:

    System.IO.TextReader reader = new System.IO.StreamReader(
               sock.GetStream(), Encoding.ASCII);
    string line;
    while ((line = reader.ReadLine()) != null)  ...;
    

    我在这里猜测 telnet 使用 ASCII。

    【讨论】:

      【解决方案2】:

      不,Stream.Read 通常不会等到它读取所有内容,而且对于网络流来说更不可能。它会读取任何可用的数据,或阻塞直到有一些数据可用,但仅此而已。

      没有服务器“完成”发送将要发送的内容的真正概念,除非:

      • a) 它会提前告诉您要发送的金额
      • b) 它表明它何时完成了某种终止数据
      • c) 它关闭连接

      您可能希望使用某种计时器来实现“继续阅读,直到其中一个阅读时间超过 5 秒”的效果。请注意,读取仍然会发生 - 您只需选择那个时间来更新 UI(或其他)。这是一个相当棘手的话题,您确实需要非常清楚地了解自己(和文档!)要做什么,以及哪个线程将处理什么。

      另一种方法是在TcpClient 上设置读取超时,但我没有这方面的经验。您可能只需要使用TcpClient.ReceiveTimeout,然后在阅读时适当地处理生成的IOException,但我对此没有任何建议。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-02
        • 2023-03-08
        • 1970-01-01
        • 2011-12-04
        • 2011-10-04
        • 1970-01-01
        • 2015-06-26
        相关资源
        最近更新 更多