除了 BOOST 网站上的那个之外,还有关于多线程客户端的好的教程吗?可以处理向服务器发送数据的多线程客户端,同时还打印服务器正在发送的内容。例如:用户输入内容并将其发送到服务器的线程,以及处理套接字并从服务器接收信息并将其打印到 cout 的线程。
1 回答
您提供的链接是有关如何使用 boost::asio 库的出色指南。一旦你了解它是如何工作的,你就可以在没有多个线程的情况下做你想做的事。
asio(异步 IO)的思想是一旦 io_service 对象完成一个操作就回调你。每当你调用 aync_xxx 时,你都会向它传递一个函数指针(或函子),一旦操作完成,就会调用它。通过这种方式,您不必在轮询 IO 上设置单独的线程阻塞。
例如,一旦完成,您想从服务器读取消息。调用 do_something(消息和消息)。这正是示例代码所做的。
因为 TCP 是基于流的协议,没有自然消息边界,所以您必须在其上定义自己的消息格式。在示例中,它为此目的定义了一个 chat_message 类。
为了读取消息,客户端遵循以下步骤,每个步骤都是在之前的 async_xxx 操作完成后作为回调的结果触发的。它还依赖于 async_read 仅在读取指定的确切字节数或发生错误时才完成的事实。
- 调用 async_connect,将 handle_connect 作为其回调传递。
- handle_connect 调用 async_read,将 handle_read_header 作为其回调传递
- handle_read_header 调用 async_read,将 handle_read_body 作为其回调传递。
- handle_read_body 最终将调用 async_read,将 handle_read_header 作为其回调传递,以便该过程为下一条消息重复自身。
请注意,在示例中,它在调用 async_read 之前在步骤 4 中执行了“cout.write...”。 您需要做的就是用您的 do_something(msg) 替换“cout.wirte..”部分。
写入部分遵循类似的回调链,唯一的区别是当没有更多消息要写入时链中断,因此我们需要检查条件并重新启动它。