处理 Telnet 协商

Handling Telnet negotiation

我正在尝试使用 C++ 和 QT 作为 GUI 来实现 Telnet 客户端。 我不知道如何处理 telnet 协商。 每个 telnet 命令前面都有 IAC,例如

IAC WILL SUPPRESS_GO_AHEAD

以下是我处理谈判的方式。

  1. 在接收缓冲区中搜索 IAC 字符
  2. 根据命令和选项,响应请求

我的问题描述如下:

  1. 似乎telnet 服务器在发送协商命令后不会等待客户端响应。 例如(发送两个或多个命令而不等待客户端响应)

    IAC WILL SUPPRESS_GO_AHEAD

    IAC WILL ECHO

遇到这种情况应该怎么处理?处理两个请求还是只处理最后一个?

  1. 如果我不响应请求,选项值是多少?它们是否设置为默认值?
  2. 为什么 IAC 字符 (255) 不会被视为数据而不是命令?
  1. 是的,允许针对不同的选项发送多个协商,而无需在每个协商后同步等待响应。

    实际上,即使没有收到回复,每一方尝试继续(可能在超时后,如果您决定等待回复)也很重要,因为根据 RFC 当不应该或不能回复时,另一方可能会出于任何原因忽略请求,而您无法控制。

    您需要考虑服务器发送的两个协商请求,因为它们都是有效请求(当然您可以选择拒绝一个或两个)。

    我建议您在注意到它们时立即处理它们(无论“处理”在您的情况下是什么意思),以免服务器在决定等待您的回复时卡住。

    Daniel J. Bernstein 在 RFC 1143 中介绍了一种可能的解决方法。它使用有限状态机 (FSM),对协商循环非常稳健。

  2. 合规服务器(合规客户端也是如此)默认所有可协商选项为 WON'TDON'T(即禁用)在连接开始时不认为它们已启用,直到 DOWILL 的请求被确认分别通过 WILLDO 回复。

    当然,并非所有服务器(或与此相关的客户端)都正常运行,但是您无法预料到对等节点可能会出现的所有行为不当的方式,因此只需假设所有选项都被禁用,直到请求启用它们 回复是肯定的。

  3. 我在这里假设您实际上要问的是如何服务器将向您发送一个 255 字节作为数据而您不会误解它作为 IAC 控制序列(反之亦然,您应该如何将 255 字节作为数据发送到服务器,而不会将其误解为 telnet 命令)。

    答案很简单,服务器(以及相反方向的客户端)发送 IAC 后跟另一个 255 字节,而不是单个字节 255,因此在将作为数据流一部分的 255 的所有值加倍。

    在通过网络接收到 IAC 后跟 255 后,您的客户端(以及相反方向的服务器)必须将其替换为数据中的单个数据字节 255流式传输 returns.

    RFC 854.

    中也有介绍