ASIO写入操作抛出std::bad_alloc:C++
ASIO write operation throws std::bad_alloc : C++
我指的是聊天客户端
我的写入操作是:
void CSession::beginWrite(const Buffer & message)
{
//Check if the socket is open or not?
bool writeInProgress = !writeQueue_.empty();
writeQueue_.push_back(message);
if (!writeInProgress) //Exception Thrown here
{
asio::async_write(socket_, asio::buffer(writeQueue_.front().received_, writeQueue_.front().buffsize),
std::bind(&CSession::handle_write, this,
std::placeholders::_1, std::placeholders::_2));
}
}
void CSession::handle_write(const asio::error_code& error /*error*/, size_t bytes_transferred /*bytes_transferred*/)
{
//std::cout << "CSession::handle_write() Called" << "(" << __FILE__ << " : " << __LINE__ << ")" << std::endl;
if (!error)
{
//std::cout << bytes_transferred << " bytes written to the socket." << std::endl;
writeQueue_.pop_front();
if (!writeQueue_.empty())
{
asio::async_write(socket_, asio::buffer(writeQueue_.front().received_, writeQueue_.front().buffsize),
std::bind(&CSession::handle_write, this,
std::placeholders::_1, std::placeholders::_2));
}
}
else
{
std::cout << "Write Error Detected" << std::endl;
std::cout << error.message() << std::endl;
state_ = false;
doClose();
return;
}
}
它运行良好。然后我尝试了负载测试,让客户端连续11分钟向服务器写入消息Client 2
,如下所示:
bool flag = false;
void setFlag(const asio::error_code& /*e*/)
{
flag = true;
}
void Client(std::string IP, std::string port)
{
CSession Session(IP, port);
Session.initSession();
asio::thread t(boost::bind(&asio::io_service::run, &(*CIOService::fetchIOService().getIO())));
asio::deadline_timer timer(*CIOService::fetchIOService().getIO(), boost::posix_time::seconds(675));
timer.async_wait(&setFlag);
while (!flag)
{
Session.write("Client 2");
}
Session.close();
t.join();
}
void main()
{
Client("localhost", "8974");
system("Pause");
}
成功写入操作2-3分钟后,代码在行抛出异常Unhandled exception at 0x75B7C42D in NetworkComponentsClient.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x026DE87C.
if (!writeInProgress) //Exception Thrown here
{
asio::async_write(socket_, asio::buffer(writeQueue_.front().received_, writeQueue_.front().buffsize),
std::bind(&CSession::handle_write, this,
std::placeholders::_1, std::placeholders::_2));
}
调试显示:
- writeQueue_ { size=16777215 } std::deque<channel::Buffer,std::allocator<channel::Buffer> >
+ [0] {received_=0x052a0ac8 "Client 2" } channel::Buffer
+ [1] {received_=0x052a0b28 "Client 2" } channel::Buffer
+ [2] {received_=0x052a0b88 "Client 2" } channel::Buffer
....
....
我可以看到writeQueue_ { size=16777215 }
的大小非常大,因此std::bad_alloc
也是如此。
为什么会有这样的行为?我可以看到来自deque的代码弹出消息如下:
if (!error)
{
writeQueue_.pop_front();
if (!writeQueue_.empty())
{
asio::async_write(socket_, asio::buffer(writeQueue_.front().received_, writeQueue_.front().buffsize),
std::bind(&CSession::handle_write, this,
std::placeholders::_1, std::placeholders::_2));
}
}
所以write deque
不应该长得这么大。
我的客户端应该运行几天,并且应该涉及大的连续数据写入。如何确保长写操作顺利进行?
你的消费者(CSession
)比你的生产者(Client
)慢得多。您的生产者正在通过尽可能快地生成消息来进行拒绝服务攻击。这是一个很好的测试。
你的消费者应该(至少一个,最好是所有):
- 检测工作是否在累积,并在发生此类情况时设置策略,如"忽略新的"、"丢弃最旧的"
- 通过对传入消息设置活动筛选器来限制消耗滞后
- 改进传入消息处理的性能
我的客户应该要跑几天,应该大量参与连续数据写入。如何确保长写操作顺利进行?
然后你需要一个比网上的例子更好的代码。
- 使用来自 Excel VBA 的 C++ dll 时"Bad DLL calling convention" - 如何解决?
- C++17 编解码器在将标准::字符串转换为标准::字符串时抛出"bad conversion"
- 对于代理容器上的迭代器来说,"least bad implementation"可能是什么?
- 组件对象模型 (COM):IMalloc::Alloc 在哪里分配内存?
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- 为什么 GetSystemMetrics (SM_CXVIRTUALSCREEN) 返回'bad'值?
- 将 lambda 传递给 STL 集时出错"bad function call"
- 新的 C++14 位分隔符处"Bad Character" Eclipse Oxygen 错误
- 使用 #define 被认为是"bad practice"吗?
- "400 Bad request"使用 OpenSSL BIO 进行请求时
- CGAL:Hausdorff距离不良Alloc
- 解密文件AES_256_CBC返回"bad decrypt"错误
- 在C++流中,eof(),fail(),bad()和good()有什么区别
- C STD ::初始化类对象中的Alloc错误错误
- make / gcc:"bad build"的可能原因是什么?
- 什么是地址0xbaddc0dedeadbead "Bad decode dead bead"
- 在多线程环境中,什么可能导致"bad file descriptor"?
- 尝试解决HackerBank上的BFS挑战时出现错误的alloc异常
- "std::vector"在调整大小时引发"bad allocation"异常
- 尝试使用 execp、dup2 和管道实现 shell,挂起或"bad file descriptor"