【问题标题】:Telnet reader will split input after 1448 charactersTelnet 阅读器将在 1448 个字符后拆分输入
【发布时间】:2012-05-04 10:12:32
【问题描述】:

我正在编写一个 java 小程序,它将打印 telnet 客户端发送到连接的内容。不幸的是,客户端拆分为 1448 个字符。

被证明有问题的代码:

char[] l = new char[5000];
Reader r = new BufferedReader(new InputStreamReader(s.getInputStream(), "US-ASCII"));
int i = r.read(line);

我无法更改 telnet 客户端读取内容的来源,所以我希望这是上述三行的问题。

【问题讨论】:

  • “分裂”是什么意思?目前尚不清楚您的实际问题是什么。您是否收到客户端发送的数据?这段代码可能没问题,问题可能出在试图从发送的数据中理解的代码中。代码在哪里?
  • 我在 while 循环中有上面的代码,所以第一次,line 将设置为“猫跑过 th”,第二次,line 将设置为“e路。”然而,字符串当然会比这更长。不过,它始终是 1448 个字符。
  • 太好了,您正确获取了数据。现在您需要编写代码来理解它。没有什么可以将角色“粘合”在一起,它们只是一个流。您可以按照您正在实施的协议规则来理解您收到的数据。
  • 问题是读入行的长度。我更喜欢读“猫跑过马路”。而不是“The cat runs across th”,然后在下一个迭代中,“e road”。
  • 所以编写代码来做到这一点。这样做的“它”不是this“它”。这个“它”只是读取数据。这就是它所做的一切。如果您想将数据组装成更大的块,请编写代码来执行此操作。问题只是你还没有编写任何代码来将字节块粘合在一起。您必须实际实现 协议以获取协议数据单元,因为它是使用协议数据单元is 定义的协议。你还没有这样做,所以你要求的是不可能的。

标签: telnet


【解决方案1】:

您期望从 TCP 层获取 telnet 协议数据单元。它只是不那样工作。您只能从实现 telnet 协议的代码中提取 telnet 协议数据单元。 TCP 层数据字节的分段是任意的,高层负责重构协议数据单元。

您看到的行为是正常的,除非您正在诊断性能问题,否则您应该完全忽略在 TCP 级别拆分数据的方式。

【讨论】:

    【解决方案2】:

    您一次只能获得 1448 个字节的原因是底层协议将传输划分为数据包。通常,此大小约为 1500,并且有一些字节用于记账,因此您只剩下 1448 字节的块。协议不保证如果您在“单次”中发送 X 字节,客户端将在单次中接收 X 字节(例如,对接收方法的一次调用)。

    正如在上面的 cmets 中已经提到的,由接收程序以对客户端有意义的方式重新组装这些数据包。通常,您执行接收并将接收到的数据附加到某个缓冲区,直到找到商定的“数据块结束”标记(例如换行符、换行符、回车符、某些符号不会出现在数据中等)。

    如果服务器是真正的 telnet 服务器 - 它的输出可能是基于行的(例如,单个数据块以“行尾”终止:回车和换行字符)。 RFC 854 可能会有所帮助——它详细说明了最初指定的 Telnet 协议。

    【讨论】:

    • 附录:理解套接字/TCP 操作的重要意义在于,输入方法不会“读取一行”,而是“一次读取一些字节数”(在本例中为 1,448)。这与典型的“从键盘读取”输入法有很大不同,后者通常终止于“行”(当用户按 Enter 键时)。
    • 此外,谨慎的做法是检查流是否有数据供您收集每次迭代。在您尝试“读取”数据时,数据可能不在流中。
    • 检查它为什么?这就是阅读所做的。它会一直阻塞,直到数据可用。
    • 如果套接字是非阻塞套接字,则不会。在非阻塞套接字上,读取不会等待数据到达。如果没有要读取的数据,则返回0(没有读取),表示发送程序还没有发送数据(或尚未到达)。
    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    相关资源
    最近更新 更多