【问题标题】:Telnet Clients and Their Treatment of EOLTelnet 客户端及其 EOL 的处理方式
【发布时间】:2012-07-30 14:38:19
【问题描述】:

这是一个相当复杂的问题,对此我深表歉意。我编写了一个 Linux C 套接字应用程序,这是一个用于简单聊天服务器的基本框架。服务器正在我的笔记本电脑上运行。客户端目前是 Telnet,直到我编写指定的客户端应用程序(希望这样会更安全)。我知道有更好的应用程序可以从客户端发送通用网络数据,但我对为什么某些事情发生在一个 Telnet 客户端上而不是另一个客户端上很感兴趣。

第一个 Telnet 客户端测试是在另一台 Linux 笔记本电脑上进行的。它按预期工作。然而,下一个是一个名为 BBSSH 的黑莓应用程序,它允许 Telnet 和 SSH 连接。我通过了 Telnet 选项,它也可以工作。除了,它不完全是。

服务器代码执行通常的read 调用以检索数据块,该数据块被视为字符串,即消息。前一个客户端读取直到我按回车键,然后它发送一串字符。但是,BB 应用程序会发送每个字符,就好像我在每个字符之后都按了 Enter 键一样,而我没有。显然,这与缓冲有关,某些客户端从用户输入中将其归类为 EOL 等。我只是无法确定它。

为了说明,这里是服务器输出它从客户端接收到的消息。

首先,来自Linux客户端的消息:

client name: this is a test

现在,对于 BBSSH:

client name: t
client name: h
client name: i
client name: s
client name:
client name: i
client name: s
client name:
client name: a
client name:
client name: t
client name: e
client name: s
client name: t

有什么帮助吗?

【问题讨论】:

    标签: c sockets networking blackberry telnet


    【解决方案1】:

    Telnet 客户端可以在线路模式或字符模式下运行。由于某种原因,BBSSH 客户端似乎在字符模式下运行。

    您的服务器可能会强制客户端进入线路模式,方法是在 telnet 连接开始时发生的协商过程中向客户端发送一条相关指令。

    您的服务器需要发送给客户端的字节序列是 0x255 0x253 0x34,翻译为“解释为命令、执行、行模式”。如果客户端愿意/能够在线路模式下操作,它应该回复 0x255 0x251 0x34 ("Interpret As Command, Will, Linemode")。

    如果这对您来说是全新的(即您的 telnet 服务器目前根本不进行任何协商),请在 Google 上搜索“telnet 协商”之类的术语或查看一些相关的 RFCS(RFC 854 是 Telnet 本身, RFC 1184 涵盖了 Linemode 选项)。

    【讨论】:

    • 啊...我怀疑这与运行在不同配置或模式下的两个客户端有关。这种行为似乎太一致了,不可能是服务器端读取量的侥幸。鉴于 Telnet 客户端只是一个测试平台,并且客户端最终将直接使用 TCP,我将仅临时嵌入该模式字节序列。感谢您提供 RFC 编号,我会查找它们 :)
    • 即使客户端发送完整的数据行,它是否仍然容易受到TCP碎片的影响?
    • @JamesMcLaughlin 是的,您仍然可以获得 TCP 级别的碎片,但这不是问题中描述的问题的原因。此外,这种碎片需要在高于 TCP 或 Telnet 的协议级别上解决 - 在这个问题中,这确实是“聊天协议”的工作。
    【解决方案2】:

    TCP 是面向流的,因此不存在“消息”之类的东西。您可能会同时收到所有数据,或者一次只收到其中的一部分。

    在您的情况下,您可能希望缓冲收到的任何内容,直到您遇到 EOL 标记。

    【讨论】:

    • 我的意思是'消息'作为我的应用程序的一个抽象概念,我知道它都是基于流和缓冲区的。我假设 read 会阻塞,直到它收到 EOF,填充缓冲区直到满足那个点?
    • 默认情况下使用 TCP 套接字,read 只是阻塞,直到一些数据(任何数据)可用。这可能是一个字节,也可能是一整行。
    • 啊,我明白了。这让我很困惑。那么 read 如何知道在数据可用时停止之前要读取多少字节?
    • 它可能会在 任何 数据可用时立即返回 - 如果您一次获得整条线路,您就很幸运了,您也有可能获得一半一行或两行在一起。您将不得不继续致电read 并在收到的数据中查找 EOL 标记。
    • 是的,但即使这样你也不能保证客户端发送后不会分片。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 2014-11-19
    相关资源
    最近更新 更多