解析应用程序协议的常规方法是什么?
给定来自已设计协议(例如 SMTP)的套接字的流,处理协议的常用方法是什么。它是基于 yacc 的解析器、基于正则表达式的方法还是其他方式?
解析应用程序协议的常规方法是什么?
给定来自已设计协议(例如 SMTP)的套接字的流,处理协议的常用方法是什么。它是基于 yacc 的解析器、基于正则表达式的方法还是其他方式?
应用层协议有很多,但我认为主要区别在于它是基于二进制还是基于文本的。两者都被广泛使用。
对于基于文本的协议,通常对输入进行标记,然后使用yacc
. 一些基于文本的协议甚至比这更容易解析,因此您可能只需拆分输入并检查它是否有意义。应该考虑编码,但它必须是您已经通过内置方法或库(例如UTF-8
. 例如,HTTP 是一个文本协议,并且很容易解析(示例来自这里):
要求:
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(在电信中经常使用)、协议缓冲区或类似的东西对消息进行编码/解码。如果可能的话,不要发明自己的二进制格式,依赖经过测试和尝试的库——这很难做到,难怪ASN.1
大多数工具都很昂贵。
这是ASN.1 UPER
,您定义了一个简单的元素,例如(此处的示例):
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
如此罕见的原因。
两种方法都有其优点/缺点。基于文本的协议更容易正确、调试和理解。不过,他们通常很健谈,在某些情况下,这很重要。这是选择 eg 的时候ASN.1 PER
,这很难实现或调试,但非常紧凑。