基于套接字的应用协议解析的传统方法

时间:2013-02-14 19:18:43

标签: parsing sockets networking network-protocols

解析应用程序协议的常规方法是什么?

给定来自已设计协议(例如SMTP)的套接字的流,处理协议的常用方法是什么。它是基于yacc的解析器,基于正则表达式的方法还是其他方式?

1 个答案:

答案 0 :(得分:2)

有许多应用层协议,但我认为主要区别在于它是二进制还是基于文本。两者都被广泛使用。

对于基于文本的协议,通常会对输入进行标记,然后使用yacc之类的内容对其进行解析。一些基于文本的协议甚至比这更容易解析,因此您可能只是拆分输入并检查它是否有意义。编码应该被考虑在内,但它必须是您已经通过内置方法或库以您的语言编写的例程。 UTF-8。 HTTP,例如是一个文本协议,很容易解析(例如来自here):

请求:

GET /path/file.html HTTP/1.0
From: someuser@jmarshall.com
User-Agent: HTTPTool/1.0
[blank line here]

响应:

HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Content-Type: text/html
Content-Length: 1354

<html>
<body>
<h1>Happy New Millennium!</h1>
(more file contents)
  .
  .
  .
</body>
</html>

大多数程序员都可以为此编写解析器,即使您最好依赖经过充分测试和完整的库实现。

二进制协议虽然有些不同。第一件事是使用例如编码/解码消息。 ASN.1(经常在电信中使用),protocol buffers或类似的东西。如果可能的话,不要发明自己的二进制格式,依靠经过测试和尝试过的库 - 这很难做对,难怪,例如对于ASN.1,大多数工具都很昂贵。

这是ASN.1 UPER,您可以定义一个简单的元素,例如(例如here):

myQuestion FooQuestion ::= {
    trackingNumber     5,
    question           "Anybody there?"
}

它会像这样编码:

01 05 0e 83 bb ce 2d f9 3c a0 e9 a3 2f 2c af c0

通过所有的位移和屏蔽,实现起来并不容易 - 这就是为什么支持ASN.1的开源PER库非常罕见。

两种方法都有其优点/缺点。基于文本的协议更容易正确,调试和理解。但它们通常很健谈,在某些情况下这很重要。这是当人们选择例如ASN.1 PER,这很难实现或调试,但非常紧凑。