简介

boost的asio采用的是Proactor模型,该模型的核心思想就是异步IO,IO在事件循环中,每个异步IO都绑定对应的回调函数,当IO完成后,对应的回调函数会在事件循环中执行。

异步并发模型说明

一个TcpServer监听指定的端口,当有客户端请求到来时,会建立一个与之对应的会话,会话的生命周期与用户连接的生命周期一致。

每个异步IO,我们都绑定了一个与之对应的回调函数,这样异步完成之后,会立刻执行对应的回调函数。注意std::enable_from_this的使用方式,为了在回调中使用对应的数据,同时也为了可以智能地管理生命周期,我们直接在异步函数中获取对象本身的智能指针,该类及其对应的方法可以帮助我们实现目的,具体参考代码。

io_context可以理解为一个事件循环,当事件循环上有事件时,执行io_context::run()的线程就会获取对应的事件回调函数,并执行。如果要一个事件循环有多个线程并发执行回调,需要并发执行run函数即可,具体参考main.cpp的方式。io_context::run()如果没有对应的任务,则会自动退出,我们使用work_guard的模式,使之始终运行。

该框架是一个最基础的异步IO的Proactor模型,更复杂的业务逻辑,也只需要在对应的模型下,添加有关的组件即可。

注意,下面的代码不是一个安全的并发模型,这里只是讲了一个代码示例而已,简化复杂度;异步回调写给客户端数据的时候,会有写竞争的情况出现。

代码示例

基于boost 1.70和C++14
CMakeLists.txt

# cmake_minimum_required(VERSION <specify CMake version here>)
project(boost_asio)set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS -pthread)
add_executable(boost_asio main.cpp TcpServer.hpp Session.hpp)

Session.hpp

//
// Created by Erick on 2020/2/19.
//#ifndef BOOST_ASIO_SESSION_HPP
#define BOOST_ASIO_SESSION_HPP#include <boost/asio/ip/tcp.hpp>
#include <iostream>class Session : public std::enable_shared_from_this<Session> {using SessionSocketPtr = std::shared_ptr<boost::asio::ip::tcp::socket>;
public:explicit Session(SessionSocketPtr sk) : m_socket(std::move(sk)) {}void start() {boost::asio::async_read_until(*m_socket, m_streamBuf, "\r\n",[self = shared_from_this()](const boost::system::error_code &ec,std::size_t bytes_transferred) {if (ec.failed()) {std::cout << "session error: " << ec.message() << ", thread_id: "<< std::this_thread::get_id() << std::endl;return;}std::cout << "Thread: " << std::this_thread::get_id() << ", Get User data: "<< std::istream(&self->m_streamBuf).rdbuf()<< std::endl;self->start();  // 异步继续读});}private:SessionSocketPtr m_socket;boost::asio::streambuf m_streamBuf;
};#endif //BOOST_ASIO_SESSION_HPP

TcpServer.hpp

//
// Created by Erick on 2020/2/19.
//#ifndef BOOST_ASIO_TCPSERVER_HPP
#define BOOST_ASIO_TCPSERVER_HPP#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include "Session.hpp"// 异步的TCP服务器
class TcpServer : public std::enable_shared_from_this<TcpServer> {public:explicit TcpServer(boost::asio::io_context &ioc, int port) :io_context(ioc),m_acceptor(ioc, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) {std::cout << "start TcpServer...\n";}TcpServer(TcpServer &) = delete;TcpServer(TcpServer &&) = delete;void start() {auto socket = std::make_shared<boost::asio::ip::tcp::socket>(io_context);m_acceptor.async_accept(*socket,[socket, self = shared_from_this()](boost::system::error_code ec) {if (ec.failed()) {std::cout << "async_accept error: " << ec.message() << std::endl;}auto session = std::make_shared<Session>(socket);session->start();  // 这里启动一个会话std::cout << "thread_id: " << std::this_thread::get_id() << ", create a session\n";self->start();     // 继续重新启动});}private:boost::asio::io_context &io_context;boost::asio::ip::tcp::acceptor m_acceptor;
};#endif //BOOST_ASIO_TCPSERVER_HPP

main.cpp

#include <iostream>
#include <thread>
#include "TcpServer.hpp"const auto N = std::thread::hardware_concurrency();
using work_guard_type = boost::asio::executor_work_guard<boost::asio::io_context::executor_type>;int main() {std::cout << "begin asio model" << std::endl;boost::asio::io_context io_context;work_guard_type work_guard(io_context.get_executor());  // 启动work_guard,即使没有任务也不停止io_contextstd::vector<std::thread> threads;for (auto i = 0; i < N; ++i) {threads.emplace_back(std::thread([&]() {io_context.run();}));}int port;std::cout << "input port: ";std::cin >> port;auto tcpServer = std::make_shared<TcpServer>(io_context, port);tcpServer->start();  // 异步启动服务器,不阻塞for (auto &t: threads) {if (t.joinable()) {t.join();}}std::cout << "end asio model" << std::endl;return 0;
}

参考资料:

  • https://dens.website/tutorials/cpp-asio/multithreading-2

boost.asio异步并发Tcp服务器相关推荐

  1. Boost:基于boost::asio的延迟tcp服务器测试程序

    Boost:基于boost::asio的延迟tcp服务器测试程序 实现功能 C++实现代码 客户端源码 服务端源码 实现功能 boost::asio模块,基于boost::asio的延迟tcp服务器测 ...

  2. boost asio 异步实现tcp通讯

    一.前言 boost asio可算是一个简单易用,功能又强大可跨平台的C++通讯库,效率也表现的不错,linux环境是epoll实现的,而windows环境是iocp实现的.而tcp通讯是项目当中经常 ...

  3. boost asio 文件服务器,使用boost ASIO库封装TCP服务器类

    使用异步TCP方式,可在此基础上增加更多功能. 头文件AsioTcp.h: #pragma once #include #include #include typedef boost::asio::i ...

  4. boost::asio编程-同步TCP

    boost.asio库是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型. boost.asio库支持TCP.UDP.ICMP通信协议. 下面介绍同步TCP模式: ...

  5. c++语言 tcp例子,C++ boost::asio编程-同步TCP详解及实例代码

    boost::asio编程-同步TCP boost.asio库是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型. boost.asio库支持TCP.UDP.IC ...

  6. Boost:基于boost::asio的延迟udp服务器测试程序

    Boost:基于boost::asio的延迟udp服务器测试程序 实现功能 C++实现代码 客户端源码 服务端源码 实现功能 boost::asio模块,基于boost::asio的延迟udp服务器测 ...

  7. tcp并发服务器_在Go中构建并发TCP服务器

    tcp并发服务器 本文是Mihalis Tsoukalos的"围棋"系列的一部分. 阅读第1部分: 在Go中创建随机,安全的密码 . TCP和UDP服务器无处不在,通过TCP / ...

  8. go高性能tcp服务器,在Go中构建并发TCP服务器

    开发一个并发TCP服务器,该服务器仅使用大约65行GO代码生成随机数. TCP和UDP服务器随处可见,通过TCP/IP网络为网络客户端提供服务.在本文中,我将在GO编程语言,返回随机数.对于来自TCP ...

  9. go tcp客户端自动重连_在Go中构建并发TCP服务器样例

    开发一个并发TCP服务器,只使用大约65行Go代码生成随机数. 本文是Mihalis Tsoukalos的Go系列的一部分.阅读第1部分:在Go中创建随机安全密码. TCP和UDP服务器无处不在,通过 ...

最新文章

  1. c++ 类的定义与使用
  2. 安装Nginx的方法教程
  3. combobox绑定数据
  4. 高清晰电影的文件后缀解析
  5. GPT语言模型:通过生成式预训练改善语言理解 OpenAI 2018
  6. Pulseaudio调用alsalib write()流程(十六)
  7. gerrit权限控制
  8. 单片机学习日记- Day12
  9. 通用单目标跟踪综述《Handcrafted and Deep Trackers: A Review of Recent Object Tracking Approaches》
  10. kubernetes使用二进制方法安装部署k8s的v1.23版本安装步骤
  11. 邮件发回软件错误信息
  12. Reinitialized existing Git repository in xxx
  13. android 手机 对比,看!Android平台三款手机浏览器对比评测
  14. 写在最后——如何做好一个语音助手
  15. 【Android UI】ListView系列一(基础篇)
  16. CSDN博客微信登录竟然强制扫码关注登录(又来了)
  17. Resid------set
  18. 根据特征重要性进行特征选择
  19. 如何用代码上传头像,并添加自己的版权信息?
  20. 软件工程实践——结对作业一

热门文章

  1. jmeter使用if控制器_Jmeter 常见逻辑控制器详解
  2. What day is that day? 模拟
  3. 要不要借钱给好朋友?救急不救贫
  4. bash脚本使用记录
  5. PIL image.convert('RGB')在数据生成中真的比较好吗?
  6. Python3.x中的三目运算实现方法
  7. LeetCode 70. 爬楼梯 (递归斐波那契 | 动态规划)
  8. leetcode894.AllPossibleFullBinaryTrees
  9. 【分享】如何长时间高效学习
  10. Qt界面UI之QML初见(学习笔记四)