boost::asio async_accept 杀死 ioservice
Posted
技术标签:
【中文标题】boost::asio async_accept 杀死 ioservice【英文标题】:boost::asio async_accept kill ioservice 【发布时间】:2014-03-05 11:00:17 【问题描述】:你能帮我解决一点小问题吗?
我有 2 节课: 表格1 async_srv
当我启动应用程序时,Form1 创建 async_srv 实例。 并听我的套接字,所有收到的数据都发送到主类并从她那里返回答案。 当得到-1时,我想要destoy接受器/服务/线程和我的应用程序。 但这行不通。 有什么建议吗?
我的 async_srv.h
#include "Form1.h"
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
typedef boost::shared_ptr<boost::asio::ip::tcp::acceptor> acc_ptr;
class async_srv
private:
boost::thread* srv_thread;
boost::asio::streambuf response;
std::stringstream s;
int stop;
TForm* ourForm;
boost::shared_ptr<boost::asio::io_service> m_ioservice;
protected:
void start();
void start_accept(acc_ptr acc,socket_ptr sock);
void handle_accept(acc_ptr acc, socket_ptr sock);
public:
__fastcall async_srv(TForm* Form1);
void kill();
;
我的 async_srv.cpp
fastcall async_srv::async_srv(TForm* Form1): m_ioservice(boost::make_shared<boost::asio::io_service>())
//create Pointer to main form
ourForm = Form1;
//create thread to async recieve for realease this class
srv_thread = new boost::thread(boost::bind(&async_srv::start, this));
void async_srv::start()
//create acceptor, and socket.
acc_ptr acc(new boost::asio::ip::tcp::acceptor(*m_ioservice, ep));
socket_ptr sock(new boost::asio::ip::tcp::socket(*m_ioservice));
//start_accept
start_accept(acc,sock);
m_ioservice->run();
void async_srv::start_accept(acc_ptr acc,socket_ptr sock)
// async accept
acc->async_accept(*sock, boost::bind(&async_srv::handle_accept, this, acc, sock));
void async_srv::handle_accept(acc_ptr acc, socket_ptr sock)
//loop for recieve data
while (boost::asio::read(*sock, response, boost::asio::transfer_at_least(1), error))
s << &response;
if (s.str() != "")
//recieve answer from main
stop = ourForm->update(s.str());
if(stop == -1)
//kill our class and application
acc->close();
kill();
Application->Terminate();
return;
s.str(std::string());
response.consume(response.size());
start_accept(acc,sock);
void async_srv::kill()
m_ioservice->stop();
srv_thread->~thread();
【问题讨论】:
手动调用srv_thread
的析构函数听起来是个非常糟糕的主意。另外,您能否发布SSCCE,因为目前尚不清楚您的async_src
课程是如何使用的。
杀死线程不是主要问题,我可以使用中断而不是析构函数。主要问题,服务在 stop() 之后不会停止接受
async_src 用于从 tcp/ip 套接字接收数据。
你确定kill()
被调用了吗?看一下代码,如果sock
在没有任何数据的情况下关闭,或者ourForm->update()
在链中第一次被调用时返回除-1
之外的任何值,则在start_accept()
和handle_accept()
之间形成一个紧密的异步链由于sock
的状态导致操作失败。接受操作将立即失败,因为sock
已打开,读取操作将立即失败,因为文件结束,将s.str()
留空,不再查询表单。
我的错误是在我的句柄上调用 start_accept 方法,只需替换 "start_accept(acc,sock)" 以创建新的 "async->accept",一切正常。
【参考方案1】:
如果您想停止接受新连接 - 让接受者成为成员并在需要时关闭它:
void async_srv::kill()
// avoid closing from another thread
m_acceptor.get_io_service().post(()[this] m_acceptor->close(); );
如果m_ioservice
仅服务于接受器,关闭它将破坏async_accept-->handle_accept-->...
链并最终使m_ioservice::run()
退出,因为它会耗尽工作。 (当然,你不应该打电话给~thread
。)
【讨论】:
我使用了 boost 1.39,我的接受器没有方法 get_io_service() @user2393500 它被称为io_service()
。
我知道,对不起我的错误。 IDE 不会在提示中显示此方法。
我已经关闭接受者:if(stop == -1) acc->close();杀();应用程序->终止();
@user2393500 我猜问题出在代码的其他地方。尝试在调试器中调试它 - 设置断点,单步执行代码等。以上是关于boost::asio async_accept 杀死 ioservice的主要内容,如果未能解决你的问题,请参考以下文章
boost::asio::ip::tcp::acceptor 在使用 async_accept 接收连接请求时终止应用程序
boost::asio async_accept 杀死 ioservice
Boost asio async_accept 在 Windows 下工作,但在 FreeBSD 下失败。怎么了?
Boost asio 获取“错误代码:125 操作已取消”[关闭]