异步操作思想
  用户发起异步事件,asio将这些异步事件投递到一个队列中,用户发起的操作就返回了,io_service::run会处理异步事件队列中的所有的异步事件,它会将这些事件交给操作系统处理,操作系统处理完成之后会丢到asio的事件完成的队列中,io_service发现有完成队列中有完成事件了,就会通知用户处理完成事件。 所以用户要发起一个异步操作需要做三件事:

  调用asio异步操作接口,发起异步操作;如:async_connect、async_read、async_write,这些异步接口需要一个回调函数入参,这个回调函数在事件完成时,由io_service触发。
  调用io_service::run处理异步事件;发起一个异步操作,必须要保证io_service::run,因为io_service通过一个循环去处理这些异步操作事件的,如果没有事件就会退出,所以要保证异步事件发起之后,io_service::run还在运行。要保证一直run的一个简单办法就是使用io_service::work,它可以保证io_service一直run。
  处理异步操作完成事件;在调用异步接口时会传入一个回调函数,这个回调函数就是处理操作完成事件的,比如读完成了,用户需要对这些数据进行业务逻辑的处理。

  asio的的核心是io_service, 理解了asio异步接口的机制就容易找出使用asio过程中出现的问题了,在这里把一些常见的问题列出来,并分析原因和提出解决方法。

  问题1:为什么我发起了异步操作,如连接或者写,对方都没有反应,好像没有收到连接请求或者没有收到数据? 答案:一个很可能的原因是io_service在异步操作发起之后没有run,解决办法是保持io_service的run。
  问题2:为什么发送数据会报错? 答案:一个可能的原因是发送的数据失效了,异步发送要求发送的数据在回调完成之前都有效,异步操作只是将异步事件句柄投递到io_service队列中就返回了,并不是阻塞的,不注意这一点,如果是临时变量的数据,除了作用域就失效了,导致异步事件还没完成时数据就失效了。解决办法,保证发送数据在事件完成之前一直有效。
  问题3:为什么监听socket时,会报“函数不正确”的异常? 答案:因为监听时,也要保证这个socket一直有效,如果是一个临时变量socket,在调用异步监听后超出作用域就失效了,解决办法,将监听的socket保存起来,使它的生命周期和acceptor一样长。
  问题4:为什么连续调用异步操作时会报错? 答案:因为异步操作必须保证当前异步操作完成之后再发起下一次异步操作。解决办法:在异步完成事件处理完成之后再发起新的异步操作即可。
  问题5:为什么对方半天收不到数据,过了半天才一下子收到之前发送的数据? 答案:因为socket是流数据,一次发送多少数据不是外界能控制的,这也是所谓的粘包问题。解决办法,可以在接收时指定至少收多少的条件,或者做tcp分包处理。
  说了这么多,还是来看看例子吧,一个简单的通信程序:服务端监听某个端口,允许多个客户端连接上来,服务器将客户端发来的数据打印出来。 先看看服务端的需求,需求很简单,第一,要求能接收多个客户端;第二,要求把收到的数据打印出来。

  要求能接收多个客户端是第一个要解决的问题,异步接收需要用到acceptor::async_accept,它接收一个socket和一个完成事件的回调函数。前面的问题3中提到监听的这个socket不能是临时变量,我们要把它保存起来,最好是统一管理起来。可以考虑用一个map去管理它们,每次一个新连接过来时,服务器自动分配一个连接号给这个连接,以方便管理。然而,socket是不允许拷贝的,所以不能直接将socket放入容器中,还需要外面包装一层才可以。

  第二个问题是打印来自客户端的数据,既然要打印就需要异步读数据了。异步读是有socket完成,这个socket还要完成读写功能,为了简化用户操作,我将socket封装到一个读写事件处理器中,这个事件处理器只具备具备读和写的功能。服务器每次监听的时候我都会创建一个新的事件处理器并放到一个map中,客户端成功连接后就由这个事件处理器去处理各种读写事件了。 根据问题1,异步读写时要保证数据的有效性,这里我将一个固定大小的缓冲区作为读缓冲区。为了简单起见我使用同步发送,异步接收。

转载于:https://www.cnblogs.com/shirelyme/p/4461530.html

boost asio异步通信相关推荐

  1. 基于Boost.Asio的异步通信服务器设计与开发

     boost::asio 通讯服务器实践 1. 开发环境搭建 1.1. Asio准备 万事开头难.对于一个C++的陌生者,编译一个开源的代码并不是一件轻松愉快的事情.为使大家在审阅和检测本代码可使 ...

  2. boost::asio使用UDP协议通信源码实现

    说明:以下源码来自参考文献[1], 比原文更丰富, 更有指导意义, 方便日后参考. udp servr端源码 //g++ -g udp_server.cpp -o udp_server -lboost ...

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

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

  4. boost::asio中的C/S同步实例源码

    近来狂热地研究boost的开发技术,现将读书笔记整理如下: 需要说明的是, 本博该专题下面关于boost的源码是采用boost1.55版本, 运行在Ubuntu 14.04 64bit下面, 使用ap ...

  5. muduo 与 boost asio 吞吐量对比

    muduo (http://code.google.com/p/muduo) 是一个基于 Reactor 模式的 C++ 网络库,我在编写它的时候并没有以高并发高吞吐为主要目标,但出乎我的意料,pin ...

  6. boost::asio::streambuf 基本用法和注意事项

    streamsize  sgetn(char_type *store,streamsize n)    返回缓冲区下n个字符并存储到store中,并将缓冲区位置后移n个字节 代码说明:本来是想不断的通 ...

  7. boost.asio包装类st_asio_wrapper开发教程(2014.5.23更新)(一)-----转

    一:什么是st_asio_wrapper 它是一个c/s网络编程框架,基于对boost.asio的包装(最低在boost-1.49.0上调试过),目的是快速的构建一个c/s系统: 二:st_asio_ ...

  8. boost asio io_service学习笔记

    转自:http://hi.baidu.com/jrckkyy/blog/item/e86835d61e60722506088b6a.html 构造函数 构造函数的主要动作就是调用CreateIoCom ...

  9. Boost asio 定时器

    Boost asio入门学习笔记 版权声明:本文为博主原创文章,未经博主允许不得转载.文章中有连接失效或是技术谬误的地方,请与我联系. https://blog.csdn.net/luchengtao ...

最新文章

  1. java phantomjs 2.1.1_Java之网络爬虫WebCollector2.1.2+selenium2.44+phantomjs2.1.1
  2. MySQL之父等国际数据库掌门人齐聚,1024 程序员节全体大会重磅官宣!
  3. DataFrame 数据去重
  4. 清华开源ResRep:剪枝SOTA!用结构重参数化实现CNN无损压缩 | ICCV 2021
  5. Ubuntu 11.10更新源地址列表更改方法及下载
  6. 牛客第四次多校Maximum Mode
  7. AngularJS学习笔记一:简单入门
  8. C++大学教程(第九版)2016-07 保罗·戴特尔 (Paul Deitel)、 哈维·戴特尔 (Harvey Deitel)_cafbe(C++中文版)
  9. MySQL数据库-笔记04【查询练习题*8道(附解析)】
  10. linux下串口的阻塞和非阻塞操作
  11. Learning-Python【0】:Windows环境下Python2和Python3的安装
  12. 投资理财web后端系统_银行理财产品有风险吗?最大风险是什么?
  13. 实例具体解释Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)...
  14. Android 开发工具下载
  15. 大型企业通用ERP进销存源码 ASP.Net开发系统源码
  16. ELK-部署Logstash
  17. 如何引用服务器lua文件,Lua教程(一):在C++中嵌入Lua脚本
  18. 麻省理工大学线性代数1806(2)消元法及矩阵消元法 矩阵行变换、列变换 置换矩阵 逆矩阵 如沐春风、如饮甘露、醍醐灌顶的线性代数
  19. 黑苹果——推荐台式机(翻译自tonymacX86)
  20. 微信公众号的附件链接怎么弄

热门文章

  1. linux 0644权限,Linux 中的权限 -- 0755 和 0644
  2. Hive压缩存储(以Parquet为例)
  3. Flink 读取 Mysql
  4. Spring容器和Spring应用上下文的理解
  5. Chrome DevTools
  6. 检测SQL注入式攻击代码
  7. sersync+rsync 数据同步配置
  8. zabbix专题:第六章 动作Actions、告警方式Medias
  9. js 给json添加新的字段,或者添加一组数据,在JS数组指定位置删除、插入、替换元素...
  10. JAX-WS(三)构建简单webservice部署到tomcat上