最近我开始使用套接字。我意识到,当从网络流中读取数据时,您无法知道有多少数据进入。因此,您要么事先知道必须接收多少字节,要么知道哪些字节。
由于我目前正在尝试实现 C# WebSocket服务器,因此我需要处理 HTTP 请求。HTTP 请求可以有任意长度,因此事先知道多少字节是不可能的。但是一个 HTTP 请求总是有一定的格式。它从请求行开始,然后是零个或多个标头等。所以有了所有这些信息,它应该很简单,对吧?
没有。
我想出的一种方法是读取所有数据,直到识别出特定的字节序列。StreamReader 类有一个ReadLine
方法,我相信它是这样工作的。对于 HTTP,一个合理的分隔符是分隔消息头和正文的空行。
这里明显的问题是需要一个(最好是短的)终止序列,比如换行符。甚至 HTTP 规范也建议这两个相邻的 CRLF 不是一个好的选择,因为它们也可能出现在消息的开头。毕竟,两个 CRLF 无论如何都不是一个简单的分隔符。
因此,将该方法扩展到任意类型 3 语法,我得出结论,解析数据的最佳选择是有限状态机。我可以一个字节一个字节地将数据提供给机器,就像我从网络流中读取它一样。一旦机器接受输入,我就可以停止读取数据。此外,FSM 可以立即捕获重要的令牌。
但这真的是最好的解决方案吗?逐个字节地读取并使用自定义解析器对其进行验证似乎既乏味又昂贵。FSM 要么很慢,要么很丑。所以...
当形式已知但大小未知时,如何处理来自网络流的数据?
像HttpListener这样的类如何解析消息并快速处理呢?
我在这里错过了什么吗?这通常会怎么做?