【问题标题】:How to know a pack of data is fully received in telnet?如何知道一包数据在 telnet 中被完全接收?
【发布时间】:2015-06-03 08:07:59
【问题描述】:

我正在编写一个玩具 MUD 客户端,它使用 TCP/IP 套接字连接到远程登录服务器。

作为 MUD 客户端的一个常见功能,我应该能够在来自服务器的响应上运行一堆正则表达式,并在它们被触发时执行操作。

现在问题出现在响应很长并且在 2 个或更多 TCP/IP 数据包中收到时,因此当我在响应上运行正则表达式时它们不会匹配,因为它们还没有完成(第一部分或第二部分不会单独匹配)。

所以问题是我如何知道服务器在运行我的正则表达式之前已经完成了数据包的发送。

【问题讨论】:

    标签: telnet tcp-ip mud


    【解决方案1】:

    您可以保留一个堆栈,将数据包添加到其中,继续测试直到获得完整响应

    如果MUD(几乎)只由客户端(而不是telnet本身)播放,您可以添加分隔符,再次拥有堆栈,但不要盲目测试,在获得分隔符时进行测试。

    如果您可以发送的命令没有游戏效果,但服务器会不断回复(例如 ping),您可以将其用作各种分隔符。

    【讨论】:

    • 问题是“分隔符是什么?”您所说的“(几乎)由客户端(而不是 telnet 本身)播放”是什么意思?
    • 分隔符是你想要的任何东西,现在我用逗号分隔我的句子,用任何非字母分隔我的单词,你只需要找到或定义一个分隔符,始终将你的消息与彼此。如果玩家将通过 telnet 本身而不是您的客户端进行连接,例如您的分隔符是 %%%,他们会看到那些 %%% 而您可能不希望这样。
    • 这里有个小误会:服务器端不是我能控制的,我只是写一个通用的泥客户端。所以我不能让服务器在数据末尾添加分隔符。
    • 然后使用我回复的第一段,尽可能将其与第二段混合。保留堆栈,当你觉得字符串完成时处理它(例如,你检测到一个完整的命令字,或者 30 秒过去了没有更多的数据包> 不过在这种情况下我会注销)。如果某些命令被分隔,请在这些情况下利用。
    • 这几乎就是我的想法,但问题是它在接收数据和向用户显示数据之间造成了不必要的延迟。
    【解决方案2】:

    简短的回答是:你没有

    TCP/IP 是一个串行协议,没有的概念。

    如果您的应用层协议使用数据包(大多数都使用),那么您有两种选择:

    • 使用原生支持数据包的传输层(UDP、SCTP、...)

    • 将打包信息添加到您的数据流中

    添加打包信息最简单的方法是添加分隔符(通常是\n);显然你不能在有效负载中使用分隔符,因为它已经保留用于其他目的。

    如果您需要能够在负载中传输任何字符(因此您不能保留分隔符),请在 TCP/IP 之上使用 SLIP 之类的东西

    【讨论】:

    • 我知道它“没有数据包的概念”。但我需要以某种方式确定在我发送下一个命令之前是否没有更多数据。有时数据以“\n”结尾,有时以其他字符结尾,因此服务器显然不关心分隔符。
    • 我现在认为您没有编写服务器并且可能不会更改它。在这种情况下,您必须逐案解决。
    • 是的,那么最好的方法是什么?因为服务器在任何情况下都可能不同。我正在考虑在对数据采取行动之前等待大约 200 毫秒...
    【解决方案3】:

    你可能想多了。几乎所有的泥都用LF,即\n(一些古怪的服务器会使用CRLF\r\n,甚至\n\r)来分隔线。所以缓冲您的输入并扫描分隔符\n。找到一个后,将行移出输入缓冲区,然后运行您的正则表达式。

    一个特例是telnet 命令IAC GA,一些泥巴用它来表示提示。阅读 Telnet RFC 了解更多详细信息,https://www.rfc-editor.org/rfc/rfc854,并对泥浆特定问题进行一些研究,例如 http://cryosphere.net/mud-protocol.html

    实际上,在泥泞的情况下,您永远不会遇到排长队的问题。如果泥浆和客户之间有很多滞后,那么您就无能为力了。

    【讨论】:

    • 这个解决方案的问题是每一行都以换行结束,例如,您发送“地图”并接收周围环境的 ASCII 地图。而且我看到的提示只是以“>”结尾,仅此而已。
    • 非结构化数据(例如 'map'、'help' 命令)通常是泥浆的问题,你不会在你所问的问题级别上解决它除非您可以控制服务器和客户端。以 '>' 结尾的提示符后面可能有 LFIAC GA。你不是在扫描 IAC 吗?
    • 我确实扫描了 IAC,不幸的是,泥浆按自己的规则行事。我现在正在使用 aardwolf 作为样本泥,它以“>”结束提示。我可以在 mud 中使用一些命令来更改提示格式,但作为一般规则,通用 mud 客户端依赖预定义格式并不是一个好主意。我使用的成熟客户可以毫不费力地检测任何类型的提示。
    猜你喜欢
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 2013-09-27
    相关资源
    最近更新 更多