【发布时间】:2018-04-09 09:45:36
【问题描述】:
当我失去连接时,在我的服务器代码中,我会尝试永远在循环中重新连接。重新连接后,我会向我连接的组件发送登录消息。然后该组件发回一个看起来像“MyResponse”的登录响应
初始连接工作正常。然而,在我重新连接后,我在预期的消息之前收到垃圾,看起来像:“ýMyResponse”
谷歌搜索后。我在 Stack Overflow 上看到了很多关于 boost::asio::streambuf 的问题,该 boost::asio::streambuf 用于 boost::asio 中的异步套接字。特别是关于重用他的缓冲区。我已经听从那里的建议,并在断开连接时调用了消耗。换句话说,我调用了 boost::asio::streambuf::consume 之后我调用了我的 socket 上的shutdown 和 close 之后,在响应调用 recv_until 时在 recv 上出现错误而被回调。
我还使用了 wireshark 来确保垃圾字符没有被发送,实际上也没有。
经过多次调试后,似乎对 consume 的调用是在注入一个字符,而不是清除所有字符。
这是一个最小的例子:
#include <boost/asio.hpp>
#include <iostream>
#include <sstream>
#include <string>
int main()
{
boost::asio::streambuf buffer;
std::cout << "buffer size " << buffer.size() << std::endl;
buffer.consume(std::numeric_limits<size_t>::max());
std::cout << "buffer size " << buffer.size() << std::endl;
std::istream is(&buffer);
std::string contents;
is >> contents;
std::cout << "Contents: " << contents << std::endl;
std::cout << "buffer size " << buffer.size() << std::endl;
return 0;
}
输出:
buffer size 0
buffer size 1
Contents: ²
buffer size 0
预期输出:
buffer size 0
buffer size 0
Contents:
buffer size 0
如果我不使用消费,我会在我的服务器代码中收到一些消息,在断开连接之前,在重新连接后的第一条消息之前。
如果我确实使用消耗,我会得到一个垃圾字符。
见:
Working with boost::asio::streambuf
【问题讨论】:
-
@Justin,根据 boost 文档和我从发布的链接中看到的内容,调用 consume 应该清除输入序列。它应该不导致额外的字符。在重新连接后重新使用 recv 调用中的缓冲区之前,我试图清除我的套接字上的 recv 调用中的任何剩余数据。使用附加信息编辑了帖子。
-
当我现在看这个问题时,我认为这是一个很好的问题,它有一个minimal reproducible example。我不知道如何解决您的问题,但我认为这是一个好问题。干得好
-
至于为什么这个问题一开始可能会被否决,您在这里发布了大量代码。这当然不是最小的,也不是完整的,所以人们投了反对票。
-
你使用的是哪个版本的 boost?
-
粗略看一下实现表明存在溢出问题(最大
std::size_t到int导致-1),然后将其传递给gbump(),没有绑定检查可能导致未定义的行为。我可以稍后进行更详细的调查,但与此同时,要消耗整个流缓冲区,请考虑将streambuf::size()显式传递给streambuf::consume()。
标签: c++ boost-asio