我通过 TCP 套接字有连续的数据流。我可以控制服务器和客户端来实现协议。基本要求是我可以同步到数据流。理想情况下,我想发送数据包,但 TCP 是面向流的并且没有数据包的概念。所以我希望应用层来处理字节流的打包。
我找到了两种常见的策略来做到这一点:
这篇博文提供了实现细节,但我认为它依赖于“意外”接收数据包,而它不应该依赖于此。即使是Modbus TCP 实现似乎也依赖于使用长度参数调用操作系统套接字函数recv来接收“完整消息”或类似的东西,尽管根据我信任的其他来源,它们不应该这样做。
有人可以照亮这个吗?
PS:整个系统运行在完全受我们控制的 LAN 上。
背景
我们最初的开发是这样的:
然后我们需要用 C++ 实现“数据包”接收(使用 Boost ASIO),我发现 TCP 中不存在数据包概念。
这篇博文提供了实现细节,但我认为它依赖于“意外”接收数据包,而它不应该依赖
我认为您已经阅读了链接博客上的结束“警告”:
但是,由于我们正在使用网络缓冲区,因此第一个recv可能无法在一个recv中获取所有4个字符。如果您选择忽略这一点,那么在高网络负载下您的代码将会崩溃。为了防弹,您需要两个接收循环,首先确定长度,第二部分获取数据。
这就是你的答案。
在 ASIO 中,这相当于不使用 [async_]read_some
,而是我们组合读取操作
asio::[async_]read
asio::[async_]read_until
asio::[async_]read
该函数用于异步读取数据到指定的动态缓冲区序列中,直到动态缓冲区序列的获取区域包含指定的分隔符。为了处理一个组合读取导致缓冲区包含多个完整消息的情况,组合
此操作是通过零次或多次调用流的 async_read_some 函数来实现的,称为组合操作。如果动态缓冲区序列的获取区域已经包含分隔符,则该异步操作立即完成。如果您需要具体的编程建议,我建议发布带有相关代码的问题。同时,我在这个网站上有很多示例,展示了如何在不同的消息框架场景中优雅地处理组合读取(
start)。
展示如何使用组合操作正确处理每个缓冲数据的示例:unget 或 boost::asio::ip::tcp::iostream 的类似解决方案