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

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

像下面这样:

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

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

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

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

建议?

有帮助吗?

解决方案

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

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

  • a) 它提前告诉您要发送多少
  • b) 它指示何时完成某种终止数据
  • c) 关闭连接

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

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

其他提示

除了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。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top