我想使用boost :: asio(或asio独立)通过异步套接字每分钟一次查询多个网络设备。对于测试,我已经实现了一个Client类和一个控制台程序,它为一个设备执行该操作(不重复)。 像这样:
class MyClient
{
public:
MyClient(asio::io_service& io_service);
void GetData(CompletionHandler completionHandler);
};
MyClient :: GetData类在内部使用多个异步操作,其中每个操作的完成触发下一个操作,直到数据可用:
使用此类的控制台程序的工作方式如下:
int main(...)
{
asio::io_service io_service_;
MyClient c(io_service_, ...);
...
c.GetData([](std::error_code ec, const FloatVector& values){
//do something with values
});
io_service_.run();
...
}
现在我想在GUI程序中使用MyClient类,每分钟连接一次> 10个设备,但我仍然坚持整体设计。
首先,我创建了一个线程池,其中每个线程执行单个io_service实例的io_service :: run()。
现在,只要我的程序想要从设备读取数据,它就会在所有设备上循环,并且必须为每个设备创建一个MyClient实例并调用GetData()方法。
现在io_service :: run()是否在池的线程中执行,它如何与io_service一起工作?我可以简单地在GUI线程中调用MyClient :: GetData(),因为它在内部使用异步操作,或者我必须调用类似io_service :: post()的东西吗?
更新 我的代码和控制台演示大致遵循以下示例: www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/example/http/client/async_client.cpp
但是在GUI程序中,我不想在GUI线程中运行io_service.run()。现在假设我至少有一个执行io_service.run()的额外线程,并且用户按下应该启动设备读取的按钮。最终完成处理程序应将数据存储在数据库中,并向用户更新图形显示。
也许按钮处理程序可以简单地实例化MyClient并在其上调用GetData()并且一切正常,因为MyClient知道io_service并使用它f.e.在async_connect等
它是否像这样工作或者我在这里弄错了?
注意:此时我的问题不是如何处理完成处理程序中的数据!它是如何在多线程GUI程序中正确获取数据的。
答案 0 :(得分:1)
请查看此示例www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/example/http/client/async_client.cpp。这应该有所帮助。
如果你看到handle_resolve是否成功,它会调用async_connect,这将导致handle_connect被触发。如果没有错误地调用handle_connect,它会将一些数据写入连接(async_write),然后调用async_read_until(没有错误)将触发handle_read_status_line,这可能会触发handle_read_headers,这可能触发handle_read_content。
如果您发现没有明确的断开连接,因为析构函数将在内部执行此操作。
答案 1 :(得分:1)
以下是您需要做的大致概述: