在 Boost 中安排任务,同时继续当前工作

发布于 2024-11-14 20:14:22 字数 1209 浏览 2 评论 0原文

我编写了一个TCP/IP程序,其中客户端使用普通(非Boost)套接字API;即服务器绑定并监听,客户端连接。服务器使用 pthreads 一次处理多个客户端。

该程序使用 OpenSSL 在客户端和服务器之间交换会话密钥。

后来,我注意到,我需要定期执行“重新密钥”:建立会话后,我必须安排重新密钥任务,其中客户端和服务器就新的会话密钥达成一致。

一种选择是为每个客户端创建一个新线程:新线程将休眠一段时间,然后唤醒并启动重新密钥。这个选项相当昂贵,因为每个客户端都需要是多线程的。

另一种选择是使用 Boost Asio。我很遗憾我不知道这个有价值的图书馆的存在;否则,我会使用 Boost 的线程和 Boost 的套接字来编写程序。

无论如何,我想以最小的改变来完成这项工作。起初,我误解了Asio。使用 Boost 的计时器 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 模型。

我想到了两个解决方案:

  1. 生成一个执行发送和接收的函数(使用普通的套接字API),并将该函数添加到io对象的队列中,以便io.run () 按预期工作。
  2. 使用 Boost 的异步套接字 API 重写套接字函数。

有更好的解决方案吗?无论如何,您能帮我找出如何实施最佳解决方案吗?

I have written a TCP/IP program, in which the client uses ordinary (non-Boost) socket API; i.e. the server binds and listens, and the client connects. The server uses pthreads to handle several clients at a time.

The program uses OpenSSL to exchange session keys between the client and the server.

Later, I noticed that periodically, I need to perform a "re-key": After the session is established, I have to schedule a re-key task, in which the client and the server agree upon a new session key.

One option was to create a new thread for each client: The new thread will sleep for a period of time, and then awakens and initiates a re-key. This option is rather expensive, since each client needs to be multi-threaded.

Another option was to use Boost Asio. I regret I wasn't aware that this valuable library existed; otherwise, I'd coded the program using Boost's threads and Boost's sockets.

Anyway, I want to do the job with minimum change. At first, I misunderstood Asio. Using Boost's Timer 2 example, I wrote something like this:

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.)
}

This is clearly wrong, since Boost blocks at io.run(). My first perception was that the asynchronous nature of async_wait will solve the problem, but clearly I misunderstood the Asio model.

I have two solutions in mind:

  1. Generate a function in which sending and receiving is performed (using ordinary socket API), and add this function to the queue of io object, so that io.run() works as expected.
  2. Re-write the socket functions using Boost's asynchronous socket API.

Is there a better solution? In any case, could you please help me figure out how to implement the best solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神也荒唐 2024-11-21 20:14:22

一般来说,io_service::run()(或导致事件发生的其他函数,例如io_service::poll()io_servive::run_one()io_service::poll_one()) 将在自己的线程中运行。

我是 boost::asio 库的大力支持者,因为一旦你习惯使用它进行编码,它就是一个非常优雅和强大的库。但是,如果您已经编写(并且正在运行)应用程序的很大一部分,我不建议您仅仅为了利用 boost::asio 而重写它,特别是如果您只需要某种类型的异步计时器。

由于您声明每个客户端已经拥有自己的线程,因此我建议使用某种类型的哨兵,您可以定期检查该线程以指示何时需要重新生成密钥。

Generally, io_service::run() (or the other functions that cause events to happen such as io_service::poll(), io_servive::run_one() and io_service::poll_one()) would be run in their own thread.

I'm a big proponent of the boost::asio library, as once you are used to coding with it, it is a very elegant and powerful library. However, if you already have a large portion of the application written (and working) I would not suggest rewriting it just to take advantage of boost::asio, especially if you only need some type of asynchronous timer.

Since you stated that each client already has its own thread, I'd suggest using some type of sentinel that you periodically check in that thread to indicate when the re-key was necessary.

┼── 2024-11-21 20:14:22

使用重写套接字函数
Boost 的异步套接字 API。

这可能并不像看起来那么艰巨。 文档包含一个很好的从 BSD 套接字 API 到 Boost.Asio 的映射。

Re-write the socket functions using
Boost's asynchronous socket API.

This may not be such a daunting task as it might seem. The documentation includes a nice mapping from the BSD socket API to Boost.Asio.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文