我编写了一个TCP / IP程序,其中客户端使用普通(非Boost)套接字API;即服务器绑定和侦听,客户端连接。服务器使用pthreads一次处理多个客户端。
该程序使用OpenSSL在客户端和服务器之间交换会话密钥。
后来,我注意到,我需要定期执行“重新密钥”:会话建立后,我必须安排一个重新密钥任务,客户端和服务器就新的会话密钥达成一致
一种选择是为每个客户端创建一个新线程:新线程将休眠一段时间,然后唤醒并启动重新密钥。这个选项相当昂贵,因为每个客户端都需要是多线程的。
另一种选择是使用Boost Asio。我很遗憾我不知道这个有价值的图书馆存在;否则,我用Boost的线程和Boost的套接字编写了程序。
无论如何,我想以最小的改变来完成这项工作。起初,我误解了Asio。使用Boost's Timer 2示例,我写了这样的内容:
void rekey(const boost::system::error_code& /*e*/)
{
// do rekey
}
...
void main()
{
//connect to server
// schedule re-key
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::minutes(30));
t.async_wait(rekey);
io.run();
// the rest of job (i.e. sending and receiving messages in a while() loop.)
}
这显然是错误的,因为Boost在io.run()
阻止。我的第一个看法是async_wait
的异步性质将解决问题,但显然我误解了Asio模型。
我有两个解决方案:
io
对象的队列中,以便io.run()
按预期工作。有更好的解决方案吗?无论如何,您能否帮我弄清楚如何实施最佳解决方案?
答案 0 :(得分:2)
通常,io_service::run()
(或导致事件发生的其他函数,如io_service::poll()
,io_servive::run_one()
和io_service::poll_one()
)将在自己的线程中运行。
我是boost :: asio库的主要支持者,因为一旦你习惯了它的编码,它就是一个非常优雅和强大的库。但是,如果您已经编写了大部分应用程序(并且正在工作),我建议不要仅仅为了利用boost :: asio来重写它,特别是如果您只需要某种类型的异步计时器。
既然你说每个客户端都有自己的线程,我建议使用某种类型的标记,你定期检查该线程,以指示何时需要重新密钥。
答案 1 :(得分:1)
使用重写套接字函数 Boost的异步套接字API。
这可能不像看起来那么艰巨。 documentation包括从BSD套接字API到Boost.Asio的良好映射。