解析应用程序协议的常规方法是什么?
给定来自已设计协议(例如SMTP)的套接字的流,处理协议的常用方法是什么。它是基于yacc的解析器,基于正则表达式的方法还是其他方式?
答案 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
,这很难实现或调试,但非常紧凑。