(1)首先要初始化一个io_service,并且调用run方法运行起来

boost::asio::io_service iosrv;

iosrv.run();

(2)然后需要用一个iosrv的实例来初始化一个acceptor

boost::asio::ip::tcp::acceptor acceptor(iosrv);

(3)然后需要调用acceptor对象的open函数

boost::system::error_code ec;

acceptor.open(boost::asio::ip::tcp::v4(), ec);

(4)然后调用acceptor的bind函数绑定ip和端口,协议等

m_acceptor.set_option(boost::asio::socket_base::reuse_address(true) );

m_acceptor.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), ec);

(5)然后调用accptor的listen函数进行监听

acceptor.listen(10);

(6)然后调用acceptor的async_accept函数异步接受一个连接

boost::asio::ip::tcp::socket m_sock;

m_acceptor.async_accept(m_sock, std::bind(&server::on_accept, this, std::placeholders::_1));

其中m_sock 接受新连接后保存连接信息的载体

需要注意的是,当接受一个连接完成后需要再次调用m_acceptor的async_accept函数,才会再次接受下一个连接,否则不会接受新的连接

(8)接收消息可以使用tcp::socket 对象的async_read_some方法(这个函数不一定读取锁期望的全部字节就可能返回)

void async_read()
    {
        auto self(shared_from_this());
        m_socket.async_read_some(boost::asio::buffer(m_buff), 
            [this, self](const boost::system::error_code &ec, size_t byte_transffered) {
            if (!ec)
            {
                async_write(byte_transffered);
            }
            else
            {
                std::cout << "read error" << ec << std::endl;
            }
        });
        
    }

或者可以使用boost::asio::async_read方法,但是这个方法是读指定长度的数据,如果没有读到所期望的字节数,就不会返回,直到等到所有期待的字节或者出错的时候才返回,

boost::asio::async_read特别适合用来获取固定长度的包头和指定长度的包体,这个很适合解包

(9)发送消息可以用boost::asio::async_write()函数(不是socket类的成员函数)

void async_write(size_t byte_transffered)
    {
        auto self(shared_from_this());
        boost::asio::async_write(m_socket, boost::asio::buffer(m_buff, byte_transffered),
            [this, self](const boost::system::error_code &ec, size_t sendsize)
        {
            if (!ec)
            {
                std::cout << "send " << sendsize << " byte success." << std::endl;
                async_read();
            }
            else
            {
                std::cout << "send fail." << std::endl;
            }

}
            );
    }

如果初始化一个使用一个endpoint初始化一个acceptor,那么就不需要步骤(3)~(5),直接到调用acceptor::async_accept这一步,例如:

boost::asio::ip::tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port))

asio的异步实现机制:asio库使用epoll模型之所以能做到全异步,是因为有个io_service这个类,这个类里面会维护一个待执行的任务队列,某个线程会调用这个io_service的run方法,run方法中一直循环检测任务队列,如果有未执行的队列就执行,其他线程通过io_service的post方法,把需要执行的函数加入到任务队列里面,让执行io_service.run()方法的那个线程去执行。这样就能做到异步,任务函数执行完后可以做一个回调通知函数post方

boost的每个socket都要绑定一个io_service就是这个道理

下面是echo服务端的代码:

// boost_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <string>
#include <boost/asio.hpp>class session : public std::enable_shared_from_this<session>
{
public:session(boost::asio::ip::tcp::socket s) : m_socket(std::move(s)){}void async_read(){auto self(shared_from_this());m_socket.async_read_some(boost::asio::buffer(m_buff),//    boost::asio::async_read(m_socket, boost::asio::buffer(m_buff),[this, self](const boost::system::error_code &ec, size_t byte_transffered) {if (!ec){std::string str(m_buff.data(), byte_transffered);std::cout << "receive:" << str << std::endl;async_write(byte_transffered);}else{std::cout << "read error" << ec << std::endl;}});}void async_write(size_t byte_transffered){auto self(shared_from_this());boost::asio::async_write(m_socket, boost::asio::buffer(m_buff, byte_transffered),[this, self](const boost::system::error_code &ec, size_t sendsize){if (!ec){std::cout << "send " << sendsize << " byte success." << std::endl;async_read();}else{std::cout << "send fail." << std::endl;}});}public:boost::asio::ip::tcp::socket m_socket;std::array<char, 1024> m_buff;
};class server {
public:server(std::string ip, unsigned short port, boost::asio::io_service *pIoService):m_sock(*pIoService), m_acceptor(*pIoService){boost::system::error_code ec;m_acceptor.open(boost::asio::ip::tcp::v4(), ec);if (ec)std::cout << "open error :" << ec << std::endl;m_acceptor.set_option(boost::asio::socket_base::reuse_address(true) );m_acceptor.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), ec);if (ec)std::cout << "bind error :" << ec << std::endl;std::cout << "port:" <<  port << std::endl;m_acceptor.listen(10);}void async_accept(){m_acceptor.async_accept(m_sock, std::bind(&server::on_accept, this, std::placeholders::_1));}void on_accept(const boost::system::error_code &ec){if (!ec){std::shared_ptr<session> ptr = std::make_shared<session>(std::move(m_sock));ptr->async_read();}//重新获取连接async_accept();}public:boost::asio::ip::tcp::socket m_sock;boost::asio::ip::tcp::acceptor m_acceptor;
};int main()
{std::cout << "v2.2" << std::endl;boost::asio::io_service ioservice;server sv("", 9000, &ioservice);sv.async_accept();ioservice.run();std::cout << "end" <<  std::endl;
}

参考博文:

https://www.cnblogs.com/hanerfan/p/5161955.html

boost asio异步服务端实现步骤相关推荐

  1. boost asio 异步实现tcp通讯

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

  2. boost::asio异步模式的C/S客户端源码实现

    异步模式的服务器源码 //g++ -g async_tcp_server.cpp -o async_tcp_server -lboost_system //#include <iostream& ...

  3. boost.asio异步并发Tcp服务器

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

  4. Boost.Asio入门

    原文地址:https://mmoaay.gitbooks.io/boost-asio-cpp-network-programming-chinese/content/Chapter1.html Boo ...

  5. Boost asio 官方教程简介

    1. 概述 本章介绍了 Boost C++ 库 Asio,它是异步输入输出的核心. 名字本身就说明了一切:Asio 意即异步输入/输出. 该库可以让 C++ 异步地处理数据,且平台独立. 异步数据处理 ...

  6. 基于boost asio实现sync tcp server通信

    文章目录 一.功能介绍 二.string类型数据交互 2.1 程序源码 2.2 编译&&执行 2.3 程序执行结果 三.byte类型数据交互 3.1 程序源码 3.2 编译&& ...

  7. 使用极光推送实现分组发送和服务端集成

    推送功能在手机应用开发中越来越重要,几乎成为所有App必备的功能,由于Android本身没有消息推送机制,通常采用的是基于XMPP协议的推送,但这种开发很麻烦,因此在市场上应运而生了提供消息推送服务的 ...

  8. C# Socket服务端与客户端通信(包含大文件的断点传输)

    步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收 ...

  9. 客户端与服务端的TCP通信实现(Qt)

    一:TCP通信介绍 .TCP是面向连接的可靠传输的协议,协议规定交换的双方必须是服务端和客户端的两个角色: ---   服务端负责监听网络端口,等待客户端的连接,用连接的socket完成信息的交互: ...

  10. tomcat给android发图片,一步一步学会http获取tomcat服务端的图片,在android客户端显示...

    最简单的利用服务端来下载图片到客户端上面,刚开始接触,记录一下,同时希望帮助到新人. 在看本篇文章之前,你可以先看下这两篇文章 加载web项目时报的错误:Tomcat version 6.0 only ...

最新文章

  1. 深度学习与计算机视觉系列(9)_串一串神经网络之动手实现小例子
  2. 爬虫 wordcloud操作
  3. Kruskal实现最小生成树
  4. JSP文件如何转换成Java文件?
  5. REVERSE-PRACTICE-BUUCTF-9
  6. 在.NET环境中实现每日构建(Daily Build)--ccnet,MSBuild篇
  7. 内存恶鬼drawRect - 谈画图功能的内存优化
  8. 关于Axure RP
  9. SQL Server 2008使用问题集锦
  10. Elasticsearch 磁盘使用率超过警戒水位线,怎么办?
  11. 软件单元测试方法,单元测试的基本测试方法
  12. WEB攻防-ASP安全
  13. 可汗学院公开课:统计学笔记——基础知识、二项及泊松分布 、大数定律、正态分布
  14. LeetCode,无它,唯手熟尔(五)
  15. Android 省电模式 降频吗,开启省电模式会降频吗
  16. 黎想首谈14大权威新媒体推广平台,教你一招搭建信息流矩阵!
  17. postgres查询序列_PostgreSQL 序列使用
  18. 21点 小游戏 java代码_基于Java的21点扑克游戏的实现
  19. 有效的预防电脑辐射的方法
  20. 2015浙江理工校赛A 孙壕请一盘青岛大虾呗(简单搜索)

热门文章

  1. WordPress使用domain/wp-json/api/v1/test 无法到接口可能的原因
  2. 机器人定位误差标定模型
  3. ie首页被篡改解决方法 ie浏览器 ie浏览器首页设置 iexplore.exe触犯注册表防护规则
  4. can总线短距离不用双绞线_CAN总线布线规范
  5. 【reverse】buu-[WUSTCTF2020]level4——二叉树+IDA动态调试
  6. Edge浏览器保存主页视频的方法
  7. Unable to find a single main class from the following candidates
  8. # 你也可以在你的微信 or QQ头像添加小国旗了,超简单!
  9. android 7 sl4a,SL4A 伴随Android7 浴火重生
  10. 理解手机中的感应器模块:重力感应/光线感应/电子罗盘/陀螺仪模块功能