你要是看过basic_stream_socket的文档,里面提到async_write_some不能保证将所有要发送的数据都发出去。并且提到如果想这样做,需要使用boost asio的async_write

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/basic_stream_socket/async_write_some.html

  1. Remarks
  2. The write operation may not transmit all of the data to the peer. Consider using the async_write function if you need to ensure that all data is written before the asynchronous operation completes.

但是这几天我就遇到一个问题,以前一直都是一次发送成功的。

我想发送54个字节的数据,可是每次都是只发9个字节。因此只好自己写了一个重试发送的递归函数。也很简单,通过bind,每次传递想要发送的字节数木和发送开始位置给异步回调函数。

代码参考如下:

  1. void Sign::AfterWriteMessage(error_code const& ec, size_t bytes_transferred, size_t expected_size,  size_t offset) {
  2. if (ec) {
  3. BOOSTER_ERROR("AfterWriteMessage") << "write message failed, error code:" << ec.value()
  4. << " category name:" << ec.category().name()
  5. << " id_:" << id_
  6. << " address:" << address
  7. << " message:" << ec.message();
  8. Close();
  9. return;
  10. }
  11. BOOSTER_DEBUG("AfterWriteMessage") << "thread id: " << this_thread::get_id() << " send_buffer: " << PrintBytesAsHexString(send_buffer, bytes_transferred) << " sent size:" << bytes_transferred;
  12. BOOSTER_DEBUG("AfterWriteMessage") << "thread id: " << this_thread::get_id() << " send_buffer: " << PrintBytesAsHexString(send_buffer, expected_size) << " expected size:" << expected_size;
  13. size_t resend_size = expected_size - bytes_transferred;
  14. if (resend_size > 0) {
  15. size_t new_offset = offset + bytes_transferred;
  16. async_write(socket, buffer((void*)&send_buffer[new_offset], resend_size),
  17. strand_.wrap(bind(&Sign::AfterWriteMessage, shared_from_this(), _1, _2, resend_size, new_offset)));
  18. return;
  19. }
  20. // do your business after send succeeds
  21. }
  22. void Sign::SendMessage(size_t size) {
  23. //  BOOSTER_DEBUG("SendMessage") << "thread id: " << this_thread::get_id() << " send_buffer: " << PrintBytesAsHexString(send_buffer, size) << " size:" << size;
  24. async_write(socket, buffer(send_buffer, size),
  25. strand_.wrap(bind(&Sign::AfterWriteMessage, shared_from_this(), _1, _2, size, 0)));
  26. }

但是为什么呢?难道真的是bug. 请看下一篇。

boost::asio async_write也不能保证一次发完所有数据 一的更多相关文章

  1. boost::asio async_write也不能保证一次发完所有数据 二

    只有看boost源码才能弄明白发生了什么.首先我是将vector里面写入了数据,然后用boost::asio::buffer将vector构造成了mutable_buffer_1对象. 参考该文档的重 ...

  2. boost::asio译文

        Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...

  3. boost asio 异步实现tcp通讯

    ---恢复内容开始--- asioboost   目录(?)[-] 一前言 二实现思路 通讯包数据结构 连接对象 连接管理器 服务器端的实现 对象串行化   一.前言 boost asio可算是一个简 ...

  4. Boost.Asio技术文档

    Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...

  5. Boost.Asio的使用技巧

    基本概念 Asio proactor I/O服务 work类 run() vs poll() stop() post() vs dispatch() buffer类 缓冲区管理 I/O对象 socke ...

  6. boost asio 学习(九) boost::asio 网络封装

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A ...

  7. 浅谈 Boost.Asio 的多线程模型

    Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法. 另一种支持多 ...

  8. <转>浅谈 Boost.Asio 的多线程模型

    本文转自:http://senlinzhan.github.io/2017/09/17/boost-asio/ Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个 ...

  9. BOOST ASIO 学习专贴

    本文已于20170903更新完毕,所有boost asio 代码均为本人手抄.编译器为vs2013,并且所有代码已经上传,本文下方可下载源码 为了学习boost asio库,我是从boost的官方bo ...

随机推荐

  1. MFC逆向-消息响应函数的定位

    MFC  ==   Microsoft Foundation Class,微软基础类库,他封装了Windows API以便用户更快速的开发界面功能程序然而该库及其庞大而复杂,需要有C++的功底否则很难 ...

  2. 基于visual Studio2013解决算法导论之026二叉树

     题目 二叉树实现 解决代码及点评 #include<stdio.h> #include <malloc.h> #include <stdlib.h> typ ...

  3. ListBox控件

    主要介绍:自定义数据.绑定数据库数据 前台代码: <div> <asp:ListBox ID=" Width ="100px"> <asp: ...

  4. Ibatis的分页机制的缺陷

    我们知道,Ibatis为我们提供了可以直接实现分页的方法 queryForList(String statementName, Object parameterObject, int skipResu ...

  5. python中eval, exec, execfile,和compile [转载]

    eval(str [,globals [,locals ]])函数将字符串str当成有效Python表达式来求值,并返回计算结果. 同样地, exec语句将字符串str当成有效Python代码来执行. ...

  6. Spring Web MVC中的页面缓存支持 ——跟我学SpringMVC系列

    Spring Web MVC中的页面缓存支持 ——跟我学SpringMVC系列

  7. cmake手册详解----转

    参考链接:http://www.cnblogs.com/coderfenghc/tag/cmake/

  8. SQL 多个表之间联合查询

    非常少用join,这次学学,并备忘两篇文章! 转自:http://hcx-2008.javaeye.com/blog/285661 连接查询 通过连接运算符能够实现多个表查询.连接是关系数据库模型的主 ...

  9. 用 PS 复制权限

    用 PS 复制权限 我们要把源计算机上的文件权限复制到目的计算机上. get-acl .\s.txt | Export-Clixml sddl.xml 把 s.txt 文件的权限保存到 sddl.xm ...

  10. MongoDB系列之二(主动复制)

    目前我正在进行MongoDB的双机热备方面相关的工作.根据我目前看到的MongoDB方面的材料,MongoDB的实际部署有三种方式,分别是“主动复制”,“副本集”以及“分片副本集”. 首先我们从最简单 ...