传统的套接字应用程序协议解析方法

4

传统的应用程序协议解析方法是什么?

在已经设计好的协议(例如SMTP)的套接字流中,处理协议的通常方式是什么?它是基于yacc解析器、基于正则表达式的方法还是其他方式?


这个问题有点主观,但是答案很有趣,所以点赞。 (我看到大多数用于SMTP之类的东西的解析器都是手工制作的(非yacc)) - Anton Kovalenko
明白了,但这是一个我想知道人们通常使用的一般方法的情况。我们可以在这里收集所有的方法。 - kobrien
我们可以在这里收集所有的方法。那么,“处理协议的通常方式是什么?”:使用库。 - CodeCaster
如果我有一个自定义协议,如何在库中解析该协议? - kobrien
就我所知,我从未见过一个通信层直接由无上下文解析器驱动。 - 500 - Internal Server Error
1个回答

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(在电信中经常使用)、协议缓冲区或类似的编码/解码消息方式。如果可能,不要发明自己的二进制格式,而是依赖于经过测试和验证的库——这很难做到,难怪例如对于 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

通过位移和掩码实现并不容易,这就是为什么支持PER的开源ASN.1库如此罕见的原因。

这两种方法都有其优缺点。基于文本的协议有些更易于正确地编写、调试和理解。它们通常非常善于交流,但在某些情况下这很重要。这就是当人们选择例如ASN.1 PER时,虽然它非常难以实现或调试,但非常紧凑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接