【问题标题】:How to write a simple text based protocol, preferably in C如何编写一个简单的基于文本的协议,最好用 C
【发布时间】:2009-12-24 19:21:23
【问题描述】:

我想编写一个通过标准TCP/IP 与应用服务器通信的客户端程序。客户端可以与应用程序服务器对话,并通过简单地使用特定的基于文本的协议进行身份验证。流量将被加密,但不会有username/password。如果另一个应用程序尝试与应用程序服务器通信,并且应用程序没有使用正确的基于文本的协议,应用程序服务器将默默地丢弃数据包。

等待建议。

【问题讨论】:

  • 你特别想知道什么?
  • 你想重新发明 HTTPS 协议吗?
  • 不,我不想重新发明任何东西。这是一个关于如何让两个应用程序相互通信的学习练习......忘记加密。我希望应用程序服务器丢弃客户端应用程序无法与其正确通信的任何内容。应用服务器使用特定的协议/方言,基于文本。如果你不会说这种语言,你就会被抛弃。我希望看到安全的实施。
  • 一项学习练习可以通过研究来完成......

标签: c algorithm security protocols


【解决方案1】:

您可以使用TLV(标签长度值)的简化版本。

基本思想是定义一组消息类型,这些类型由固定大小的代码(T 表示标签)表示。根据消息的类型,它的内容(V 代表值)可以非常好,因此您可以在内容之前指定它的长度(L 代表长度)。 Length 字段也有固定大小

假设您有一条消息用于将用户数据发送到服务器。您可以定义如下消息:

0x01 0x0018 0x11 0x0003 tom 0x12 0x000F tom@hotmail.com

Tag: 0x10 User data. Length: 0x0018 Value: sub tags

    Tag 0x11: user name Length: 0x0003 Value = tom
    Tag 0x12: email. Length: 0x000F. Value = tom@hotmail.com

已编辑

我差点忘了:圣诞快乐 :)

【讨论】:

  • (+1) 不错的原语从我猜开始
  • 这不是对二进制数据更有用吗?由于 OP 想要一个基于文本的协议,比如 Tag:Value;也可以工作,而且它是人类可读的。
  • 嗯,它更适合二进制,因为标签和长度是固定大小的字段,但内容可以是任何东西。另一种选择是以 XML 格式编写协议。
【解决方案2】:

看看BEEP

您还可以在four.livejournal.com 找到一些很好的例子;他使用Ragel 状态机生成器编写an HTTP parser 取得了不错的成绩,也可以手动编写。

【讨论】:

    【解决方案3】:

    如果您对 HTTP 提供的有限功能(动词)不满意,请添加更多 verbs。这就是 REST 架构的用途。

    如果你想继续你的愚蠢之路(你在谈论重新发明 HTTPS),那么使用protocol buffers 创建一个协议——它将为你节省数小时的痛苦。

    -- 编辑--

    如果您的目标是了解 Web 服务器所涉及的编程,您可能需要阅读 FMC group into a collection of models 剖析的 apache 代码。我已多次阅读此 PDF 文件——这绝对是一座金矿。

    【讨论】:

    • 这家伙只是想学习和编写一些代码......对我来说听起来不像是一条愚蠢的道路......这叫做好奇......
    • 我全心全意地同意你的观点(我的其他帖子会告诉你我将人们指向知识)。尽管在这种情况下我确实想稍微劝阻; HTTPS 非常普遍,从重新实现它中学到的东西并不多。有数百个编写良好的开源 Web 服务器可供学习。此外,还有两本关于基于文本的协议的知识:即 Fielding 的和 Bernard-Lee 的博士论文。
    【解决方案4】:

    所有其他 cmets 都很好,像 BEEP 之类的东西,或者做一些自定义 TLV 编码可以让你一路走好,以及使用谷歌协议缓冲区之类的东西,但这些都不是我真正称之为真正简单的东西.

    一个非常简单的基于文本的协议可以只使用一个新行作为消息分隔符。这就是 IRC 的做法。它不是最有效的,但如果您的消息相当小,它可以很好地工作。您还可以在消息前加上一条更短的行,告诉接收者下一条消息有多长。

    如果您想使用轻量级框架,请查看 libevent。它可以协助您的 IO 并为您进行行分隔读取。

    如果尚未为您确定语言(协议),那么您应该首先设计,或者查看已经存在的东西 - XML、JSON 块、网络字符串等。

    【讨论】:

      【解决方案5】:

      您可以查看TCP/IP Sockets in C中的一些示例代码。

      它有很多用 C 进行客户端/服务器通信的示例。没有更多细节,很难知道你真正想要处理什么......

      【讨论】:

        【解决方案6】:

        对于定制应用程序之间的通信,您只需以 TCP 数据包的形式发送文本格式。您可以使用极其简单的文本格式,但您应该确保它以一些文本开头,这些文本可以清楚地向您的服务器标识它是来自您的客户端的数据包,而不是来自冒名顶替者的数据包。 (显然这不是非常好的安全性,但这不是你问题的重点)。

        将 XML 用于基于文本的格式是一个不错的起点。这非常容易写/读,并且灵活且可扩展,因此您可以在以后轻松地将更多信息添加到您的数据包中 - 您可能会犯的最大错误是使用无法扩展的通信格式!

        一旦您的基本通讯工作正常,您可以增强格式以发送更多信息、添加加密和其他安全措施,并考虑改用二进制(更安全、更紧凑和高效)格式。但是,您可以通过简单的小步骤进入此阶段。

        所以正确的方向:

        • 让两个程序通过 TCP 通信。在这个阶段,只需一个带有文本“bob”的简单数据包就足够了,只是为了验证消息传递是否有效。网络上有许多简单的教程可以帮助您完成这项工作,只要您弄清楚需要什么,只需几行代码。

        • 然后构建您的数据包。从最简单的方法开始,该方法为您提供唯一 ID(以验证数据包来自正确的程序)以及将来轻松向数据包添加新数据的方法。 XML 是理想的选择。不用担心安全性,只需专注于您希望在程序之间传达的实际“对话”——它们希望交换哪些数据以及如何对其进行编码。

        • 逐步改进通信协议,直到它达到您想要的 - 更小、更快、二进制、更健壮、容错、安全等。这些步骤中的每一个都将是一个有趣的小挑战,到时候你已经完成了所有这些,你会学到很多东西。

        【讨论】:

          【解决方案7】:

          查看 E S Raymond 的“The Art of UNIX Programming”中关于文本协议的章节。它涵盖了很多高层次的相关想法,有很好的例子,并解释了为什么它们是好例子。它提到了 BEEP。

          【讨论】:

            【解决方案8】:

            我最近读了一本关于这个主题的书。它被 Michael J. Donahoo 和 Kenneth L. Calvert 称为“C 语言中的 TCP IP 套接字”。如果你能负担得起,这是一本不错的教程/参考书。

            If you'd like you can try create the client<->server pair in Java,因为比较容易掌握思路,然后在C语言中重新思考下层的解决方案。

            【讨论】:

              猜你喜欢
              • 2019-12-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-01-24
              • 2011-04-26
              • 1970-01-01
              • 1970-01-01
              • 2011-07-20
              相关资源
              最近更新 更多