c++ - C++ boost asio 奇怪的缓冲区溢出
问题描述
我已经调试了2天了。我已经尝试过更简单的代码库,据说可以重现错误......但它们工作得很好。我不确定这个错误是否在于我如何滥用 boost asio 功能或其他一些 C++ 功能。
我正在编写一个 TCP 服务器,其中消息结构定义为:
uint64_t size // Size of the message, in bytes
uint64_t timestamp // Some timestamp
char *text // Some ASCII data
编码
size
代表and的 Header 类timestamp
声明为:
class Header {
private:
uint64_t buf[2];
void *data() const {
return (void *) &buf[0];
}
public:
Header() {
buf[0] = 0UL;
buf[1] = 0UL;
}
// Reads the header from the socket
void readHeader(boost::asio::ip::tcp::socket &socket, std::function<void (void)> cb);
std::size_t getHeaderSize() const {
return sizeof(buf);
}
uint64_t getDatagramSize() const {
return buf[0];
}
uint64_t getTimestamp() const {
return buf[1];
}
};
该类ImuDatagram
保存整个消息,并具有从套接字读取数据报的方法。
class ImuDatagram {
public:
Header header;
std::string theJson;
void readDatagram(boost::asio::ip::tcp::socket &socket, std::function<void (void)> cb);
void readBody(boost::asio::ip::tcp::socket &socket, std::function<void (void)> cb);
};
方法定义如下:
void Header::readHeader(boost::asio::ip::tcp::socket &socket,
std::function<void (void)> cb)
{
boost::asio::mutable_buffer asio_buf = boost::asio::buffer(data(), getHeaderSize());
boost::asio::async_read(socket, asio_buf,
[this, cb](const boost::system::error_code &ec, std::size_t bytes_transferred){
// TAG1
// bytes_transferred: 16 (as expected)
// getDatagramSize() == 116 (as expected)
// getTimestamp() == ... (as expected)
cb();
});
}
void ImuDatagram::readBody(boost::asio::ip::tcp::socket &socket, std::function<void (void)> cb) {
uint64_t dgSize = header.getDatagramSize();
uint64_t jsonSize = dgSize - header.getHeaderSize();
// TAG2
// This will throw std::bad_alloc.
theJson.reserve(jsonSize);
boost::asio::async_read(socket, boost::asio::buffer(theJson, jsonSize),
[this, &socket, cb](const boost::system::error_code &ec, std::size_t bytes_transferred) {
// Error checks omitted
cb();
});
}
void ImuDatagram::readDatagram(boost::asio::ip::tcp::socket &socket, std::function<void (void)> cb) {
header.readHeader(socket, [this, &socket, cb](){
readBody(socket, cb);
});
}
最后,main
让一切顺利的是:
tcp::acceptor imuAcceptor(ioc, tcp::endpoint(tcp::v4(), 8081));
imuAcceptor.async_accept(imuSocket, [this](const boost::system::error_code& ec)
{
// Error checks omitted
ImuDatagram imu;
imu.readDatagram(socket, [this, &imu, &socket]() {
// Do work
});
}
问题描述
- 考虑
TAG1
在Header::readHeader
. 正如预期的那样,读取了 16 个字节(标头缓冲区的大小)。我确认theJson
' 的缓冲区没有溢出。还没有错。 - 然后我们移动到
TAG2
inImuDatagram::readBody
。如前所述,这会抛出std::bad_alloc
.
作为调试的一部分,我protection
在标头之后插入了一个字节,以查看它是否会被写入。在TAG1
,它没有被写入。在TAG2
,它被写了。起初,我以为async_read
是在写入缓冲区。但事实并非如此,正如protection
我添加的字节所验证的那样。
有人可以告诉我这个(对我来说模糊的)错误在哪里吗?我使用 STDIN 而不是套接字编写了一个更简单的版本,它工作得很好。我怀疑问题不是来自套接字。
谢谢你。
解决方案
推荐阅读
- mongodb - 在 MongoDB 中动态更新和获取数据
- scheme - 在数学上,为什么这个 SICP 算法对一个数的指数模另一个数起作用?
- java - 试图理解Android中触摸处理的逻辑
- javascript - 在 JSON 文件中搜索并将值返回到 HTML 标记
- node.js - Node.js / React - 无法读取未定义的属性“地图”
- angular - Angular:从其他可观察的管道内的forkJoin返回值
- c# - ASP.NET Core - 将多个控制器参数绑定到正文
- r - 在继续使用 R Studio 以表格格式查看数据之前,如何过滤我的一个变量的数据
- javascript - 类型错误:shows.map 不是函数
- c++ - 如何可靠地“钳制”迭代器?