AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 552302
Accepted
Rick
Rick
Asked: 2019-11-15 20:48:52 +0800 CST2019-11-15 20:48:52 +0800 CST 2019-11-15 20:48:52 +0800 CST

为什么telnet被认为是一种协议?它不只是一个简单的 TCP 发送/回显程序吗?

  • 772

这更像是一个概念问题。我需要一些澄清。


今天我在学习一些套接字编程的东西,并根据Beej 的网络编程指南编写了一个简单的聊天服务器和聊天客户端。(聊天服务器接收客户端消息并将消息发送给所有其他客户端)

我复制了 聊天服务器并编写了自己的聊天客户端。

聊天客户端只是一个stdin向服务器发送输入并从服务器打印套接字数据的程序。

后来我注意到指南说我可以telnet用来连接到服务器。我试过了,它奏效了。


我对telnet不熟悉,很长一段时间我都不知道它到底是什么。

所以现在我的经历让我感到困惑:

telnet 不就是一个简单的 TCP 发送/回显程序吗?是什么让成为协议的东西如此特别?我的哑聊天客户端程序没有创建 [应用程序] 协议。

来自维基百科Communication_protocol:

在电信中,通信协议是一个规则系统, 它允许通信系统的两个或多个实体通过物理量的任何类型的变化来传输信息。

Telnet 创建什么规则?telnet host port,为原始输入/输出打开一个 TCP 流套接字?这不是规则。

tcp
  • 5 5 个回答
  • 5277 Views

5 个回答

  • Voted
  1. Best Answer
    Michael Stum
    2019-11-15T21:15:44+08:002019-11-15T21:15:44+08:00

    Telnet 在RFC 854中定义。使它(以及其他任何东西)成为协议的原因是一组规则/约束。一个这样的规则是 Telnet 是通过 TCP 完成的,并分配了端口 23——这些东西可能看起来微不足道,但需要在某个地方指定。

    你不能随心所欲地发送任何你想要的东西,有些东西是有限制和特殊意义的。例如,它定义了一个“网络虚拟终端”——这是因为当建立 telnet 时,可能会有许多不同的终端:打印机、黑白显示器、支持 ANSI 代码的彩色显示器等。

    此外,还有这样的东西:

    总之,任何一方发送 WILL XXX 以表明该方希望(提议)开始执行选项 XXX、DO XXX 和 DON'T XXX 作为其积极和消极的确认;类似地,发送 DO XXX 以指示对方(即 DO 的接收者)开始执行选项 XXX 的愿望(请求),WILL XXX 和 WON'T XXX 是肯定和否定的确认。由于 NVT 是在未启用任何选项时留下的内容,因此可以保证 DON'T 和 WON'T 响应使连接处于两端都可以处理的状态。因此,所有主机都可以实现它们的 TELNET 进程以完全不知道不支持的选项,只是简单地返回拒绝(即拒绝)任何无法理解的选项请求。

    在现代,大多数东西都不再那么重要了(再说一遍,telnet 作为协议不再被使用,不仅仅是因为它缺乏安全性)所以实际上它归结为发送/回显,除非你必须实际与终端接口。

    • 17
  2. Stephen Kitt
    2019-11-15T21:14:21+08:002019-11-15T21:14:21+08:00

    连接两个终端时“正常工作”的事实telnet本身就是一个协议决定:设计者telnet决定在 TCP 连接的任一端使用带有“网络虚拟终端”的模型,并决定在基本终端上对这些虚拟终端进行建模功能(确实是电传打字机)。

    除此之外,telnet它不仅仅是一个简单的基于 TCP 的回显服务;它支持带内发送的控制代码,用于各种目的。它被编入RFC 854。

    • 7
  3. user373503
    2019-11-15T22:10:38+08:002019-11-15T22:10:38+08:00

    提出了一个称为“Telnet”的子系统,它是围绕网络系统原语的外壳程序,允许远程主机上的电传打字机或类似终端充当服务主机上的电传打字机。

    这来自 RFC 15,在维基百科“telnet”中提到。本文还首先将 telnet 称为“应用程序协议”。

    RFC 15 是从 1969 年 9 月开始的——就在几天前,我听到了一个有趣的采访,采访了正好 50 年前建立第一个“互联网”连接的人。他的故事是这样的:

    “与 N. Armstrong 不同,我们没有想到任何特殊信息。但是在输入“lo”(表示“登录”)后,系统崩溃了。所以“lo”(如“lo and behold”)是前两个字符通过互联网传输。回想起来,我们不可能想到更好的东西。

    (这里是一些采访:wiki arpanet Kleinrock)


    Telnet 早于 TCP/IP。RFC 15 谈到“网络原语”。由于 TCP/IP,telnet 只剩下处理“其余部分”,即应用层(RFC854 中的“协商选项”)。

    是的,telnet 很简单,即使没有 TCP。RFC 15 以:

    TELNET 子系统构成了一个很快就会被超越的“0 级”网络程序。然而,它很简单,很快就可以工作了。


    “协议”与 telnet 一起使用,因为本质上两个(不同的)系统需要用一种“语言”交谈。

    RFC 854 也解释了这个概念:

    TELNET 协议建立在三个主要思想之上:首先,“网络虚拟终端”的概念......


    • 3
  4. slebetman
    2019-11-17T02:00:30+08:002019-11-17T02:00:30+08:00

    telnet 协议是一个非常简单的协议,但它确实存在。“存在”是指 telnet 客户端不会将其接收到的所有字节都发送到读取它的程序(通常是外壳程序)。

    协议是

    字节0xff(255) 表示下一个字节是 Telnet 命令。如果您想发送 0xff,那么您必须将其加倍 ( 0xff, 0xff) 以告诉 telnet 您不打算向其发送命令。

    所以是的,该协议非常简单,几乎是微不足道的。但这不是一个简单的 tcp 直通。


    远程登录命令

    如果您对可以发送到 telnet(而不是另一端的软件/服务器)的命令感兴趣,您可以阅读 RFC:https ://www.rfc-editor.org/rfc/rfc854 。基本上 telnet 定义:

      NAME               CODE              MEANING
    
      SE                  240 (0xf0)    End of subnegotiation parameters.
      NOP                 241 (0xf1)    No operation.
      Data Mark           242 (0xf2)    The data stream portion of a Synch.
                                        This should always be accompanied
                                        by a TCP Urgent notification.
      Break               243 (0xf3)    NVT character BRK.
      Interrupt Process   244 (0xf4)    The function IP.
      Abort output        245 (0xf5)    The function AO.
      Are You There       246 (0xf6)    The function AYT.
      Erase character     247 (0xf7)    The function EC.
      Erase Line          248 (0xf8)    The function EL.
      Go ahead            249 (0xf9)    The GA signal.
      SB                  250 (0xfa)    Indicates that what follows is
                                        subnegotiation of the indicated
                                        option.
      WILL (option code)  251 (0xfb)    Indicates the desire to begin
                                        performing, or confirmation that
                                        you are now performing, the
                                        indicated option.
      WON'T (option code) 252 (0xfc)    Indicates the refusal to perform,
                                        or continue performing, the
                                        indicated option.
      DO (option code)    253 (0xfd)    Indicates the request that the
                                        other party perform, or
                                        confirmation that you are expecting
                                        the other party to perform, the
                                        indicated option.
      DON'T (option code) 254 (0xfe)    Indicates the demand that the
                                        other party stop performing,
                                        or confirmation that you are no
                                        longer expecting the other party
                                        to perform, the indicated option.
      IAC                 255 (0xff)    Data Byte 255.
    

    请注意,上面的命令是专门的 Telnet 命令。它们不是任何客户端或服务器端终端协议的一部分。例如,如果你想在 unix 中终止一个进程,你通常会键入ctrl-c. 这通常作为0x03终端发送到 shell,然后发送SIGINT到 shell 正在运行的进程。但是 telnet 本身定义0xff, 0xf4了发送SIGINT到进程,这是一个 telnet 特定协议来执行它。同样,终端通常发送0x1b, 0x4b以清除当前行,但 telnet 定义0xff, 0xf8.

    • 2
  5. Aleksi Torhamo
    2019-11-16T14:29:14+08:002019-11-16T14:29:14+08:00

    现有的答案已经解释了,它telnet可以做的不仅仅是通过 TCP 流式传输输入数据不变;我想转而关注“我的哑聊天客户端程序不会创建 [应用程序] 协议”。-问题的一部分。(顺便说一句,对于实际的“TCP 上的原始数据”,您可以使用netcat代替telnet)

    仅仅因为一个协议简单或糟糕——甚至在任何地方都没有明确规定——并不意味着它不是一个协议。如果没有商定的协议,两个系统就无法通信,即使该协议只是“TCP 上的原始数据”。如果您尝试在一端使用 FTP,而在另一端使用 HTTP,那么您将遇到问题,无论哪种方式 - 如果您幸运的话,它不会起作用;如果你不是,你会得到错误的行为。(至少以前的情况是,如果您在与 HTTP 服务器相同的主机上的非标准端口上运行 FTP 守护程序,在某些浏览器上,您可以使用它来执行 XSS 并通过指向受害者的浏览器来绕过 CSRF 保护POST 到 FTP 服务器,它会在错误消息中回显 POST 的内容,浏览器会将其解释为 HTTP/0。

    问“你所说的那个东西my dumb chat client program使用什么协议?我想从我的程序中与它交谈”是一个完全有效的问题。一个可能的答案是“TCP 上的原始数据”。然而,这并不是一个详尽的答案。

    • 如果您有一些默认端口,那可能应该是答案的一部分。
    • 如果您想非常清楚,您可以指定您的意思是“普通 TCP 数据,而不是 TCP 紧急/带外数据”(这有点牵强,因为它没有任何意义,并且判断根据我见过的认为第三组 fdselect()是针对错误的人数,大多数人似乎甚至不知道存在带外数据 - 但即使这是一个不好的例子,我希望你看到我在说什么)
    • 甚至你可能没有想到的事情也可能隐含地成为协议的一部分:你如何关闭连接?你只是打电话close()还是用它shutdown()来确保所有待处理的数据都首先交付?

    您说“为原始输入/输出打开 TCP 流套接字?这不是规则。”但真的是这样吗?“你必须使用 TCP”、“你必须按原样发送数据”和“你应该使用 XXX 端口”对我来说听起来像是规则。

    (PS 我在写这篇文章时有点激动;这个答案的其余部分有点切题,并试图回答自然的后续问题“好吧,所以一切都是协议 - 这有什么影响吗?”)

    因此,请记住,每次使两个系统相互通信时,您要么使用现有协议,要么创建新协议:在为时已晚之前记录您的协议!(即最迟,当协议变得不再简单,或者开始拥有更多的用户而不仅仅是开发人员时)例如。许多早期的 P2P 协议都说“官方客户端的来源是文档”,这在复杂的项目中非常烦人,只会导致客户端使用微妙的不同协议,并且在这里和那里不兼容。

    有一句古老的格言“对你生产的东西要严格,对你接受的东西要自由” - 核心情绪很好,但坦率地说,至少它倾向于应用的方式,我认为这是废话,只会导致更多可维护性和兼容性问题。我说:详细说明(尝试考虑每一个极端情况),并且对您生产和接受的内容非常严格,您可能会预防/解决真正的错误。

    一个关于严格解决错误的例子: 几年前,某个 bittorrent 跟踪器开始出现问题:他们的一些 torrent 无法在某些客户端上运行;客户没有抱怨,他们只是得到了不同的信息哈希,因此找不到种子。他们无法弄清楚发生了什么,并宣称受影响的客户一定是有问题的——停止使用它们。Bittorrent 使用非常严格且明确规定的编码 - 并且有充分的理由:相同的输入总是会产生完全相同的编码输出字符串,因此对于相同的输入数据,[info] 哈希总是相同的。当我第一次遇到其中一个种子时,我尝试将其输入到我自己的 - 非常严格的 - 解析器中,然后它马上说:Error: Bencoded dictionary keys not sorted (last='sha1', key='private').

    所以发生了什么事?跟踪器开始自动将密钥“私有”添加到每个上传的 torrent,但只是将其添加到末尾,而不是像 bencoding 指定的那样保持字典键排序 - 它产生的内容并不严格。一些客户端仅部分解码了 torrent,并计算了未解码、未更改的字符串的哈希值。一些客户端解码了整个种子,并重新编码了他们需要散列的部分,在这个过程中正确地对键进行排序(创建一个有效的编码),并得到一个不同的散列。据我所知/回忆,没有客户抱怨数据无效——客户对他们接受的内容并不严格。那么,哪些哈希值是正确的?两者都不!两种计算哈希的方法都是正确的,但是种子被破坏了!如果即使是其中一位客户也会' 已经抱怨过,这个错误很可能会在同一天得到修复,而不是需要几个月的时间。(IIRC 几年后,我还在另一个完全不相关的跟踪器中报告了一个相同的错误;第一个的软件是内部制作的,所以它也不是相同的代码库)

    另一个例子,这次是关于极端情况:eDonkey2000 P2P 协议使用了一个名为 ed2k 的自定义散列;规范没有指定在输入数据长度完全可被块大小整除的极端情况下的行为,因此产生了两个不兼容的变体,它们为某些文件产生不同的哈希,并且不兼容。(我说的是“规范”,但由于这是一个早期的 P2P 协议,我很确定没有规范;在对协议进行逆向工程时可能会遗漏特殊情况)

    关于详细规范的必要性:很多时候,在尝试为协议编写客户端或为文件格式编写解析器时,我遇到过一种情况,即使是最初的程序员也不知道某些数据实际上是如何编码的,因为他们已经使用了一些库,但从未详细检查过它的实际作用。两个例子:

    某个 API 使用自定义 UDP 协议,带有加密的 [可变长度] 数据包 - 文档指定 AES128,但没有提及使用的填充。当询问开发人员时,响应大致如下:

    呃,我们其实不知道,我们只是在这个Java库中使用了这个函数,并且文档似乎没有提到它使用哪个填充

    某个设备的网站对与他们的保存文件的接口有这样的说法:

    无法创建或修改已保存的 *.logicdata 文件。那是因为文件是使用 boost 二进制序列化生成的,并且包含非常复杂的对象结构。事实上,我们甚至不明白它是如何工作的。Boost 序列化非常复杂。

    (注意:但实际上,对足够的文件格式进行逆向工程以导出数据并不需要那么长时间)

    其中一些示例是关于编码、文件格式或自定义算法(尽管仍然在协议内部使用,除了最后一个),但我想说所有这些都适用于所有这些。无论您谈论的是协议、文件格式、编码还是自定义算法:

    • 写一个好的规范/记录它
      • 尝试考虑所有极端情况
      • 尝试包括所有需要的细节
    • 信守规范/严格要求
    • 1

相关问题

  • 创建套接字文件是否需要 AF_INET?

  • UDP 或 TCP 打孔以连接两个对等点(每个对等点位于路由器后面)

  • 通过 TCP 构建 Unix 套接字桥

  • 连接到 IP 0.0.0.0 成功。如何?为什么?

  • Linux中哪个进程负责TCP

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve