boost::asio async_write也不能保证一次发完所有数据 二
只有看boost源码才能弄明白发生了什么。首先我是将vector里面写入了数据,然后用boost::asio::buffer将vector构造成了mutable_buffer_1对象。
参考该文档的重载形式:http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/buffer/overload24.html
- buffer (24 of 28 overloads)
- Create a new modifiable buffer that represents the given POD vector.
- template<
- typename PodType,
- typename Allocator>
- mutable_buffers_1 buffer(
- std::vector< PodType, Allocator > & data,
- std::size_t max_size_in_bytes);
- Return Value
- A mutable_buffers_1 value equivalent to:
- mutable_buffers_1(
- data.size() ? &data[0] : 0,
- min(data.size() * sizeof(PodType), max_size_in_bytes));
注意,上面的代码最后一部分就是解释了内部原理。原来是调用vector的size成员函数,然后和传入的size比较,谁小用谁。会不会是我的vector::size返回的不是54,而是9呢。
很快我加上日志追踪,果然是9. 为什么呢? 这肯定和我对vector写数据的操作有关。下面是代码片段:
- void ConfigMessage::Write(vector<char>& buffer) {
- buffer.assign(9, 0);
- // SOH
- buffer[0] = 0x01;
- // Type
- size_t i = 3;
- buffer[i++] = 'U';
- buffer[i++] = '1';
- size_t len = domain.length();
- buffer[i++] = static_cast<uint8_t>(len);
- memcpy(&buffer[i], domain.c_str(), len);
- i += len;
- uint16_t temp = Int16ToBigEndian<uint16_t>(port);
- memcpy(&buffer[i], &temp, 2);
- i += 2;
- buffer[i++] = timezone;
我基本上当作一个C的缓冲区在用memcpy来填入数据,因此vector的size成员不能正确反映实际的数据。因此我在最后加上一个调用:
- buffer.resize(size_);
再测试。问题解决。
所以,当用vector构造buffer时要小心他的最小规则。这个问题是我自己的逻辑造成的。‘
不过在之前的那篇文章中写的递归保护代码也有保险作用。万一哪天自己又犯了错误,至少它能保证数据全部发完。
boost::asio async_write也不能保证一次发完所有数据 二的更多相关文章
- boost::asio async_write也不能保证一次发完所有数据 一
你要是看过basic_stream_socket的文档,里面提到async_write_some不能保证将所有要发送的数据都发出去.并且提到如果想这样做,需要使用boost asio的async_wr ...
- boost::asio译文
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...
- boost asio 异步实现tcp通讯
---恢复内容开始--- asioboost 目录(?)[-] 一前言 二实现思路 通讯包数据结构 连接对象 连接管理器 服务器端的实现 对象串行化 一.前言 boost asio可算是一个简 ...
- Boost.Asio技术文档
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...
- Boost.Asio的使用技巧
基本概念 Asio proactor I/O服务 work类 run() vs poll() stop() post() vs dispatch() buffer类 缓冲区管理 I/O对象 socke ...
- boost asio 学习(九) boost::asio 网络封装
http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A ...
- 浅谈 Boost.Asio 的多线程模型
Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法. 另一种支持多 ...
- <转>浅谈 Boost.Asio 的多线程模型
本文转自:http://senlinzhan.github.io/2017/09/17/boost-asio/ Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个 ...
- BOOST ASIO 学习专贴
本文已于20170903更新完毕,所有boost asio 代码均为本人手抄.编译器为vs2013,并且所有代码已经上传,本文下方可下载源码 为了学习boost asio库,我是从boost的官方bo ...
随机推荐
- TCP/IP之TCP连接的建立与中止状态分析
TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次握手. 1.连接的建立: c端发起请求同步(用SYN段等于1的TCP报文),确认某个端口是否监听: s端应答(用ACK段等于1的TCP ...
- JavaScript 高级程序设计(第3版)笔记——chapter4:变量、作用域和内存问题
Chapter4 变量.作用域和内存问题 l 理解基本类型和引用类型的值 l 理解执行环境 l 理解垃圾收集 4.1基本类型和引用类型的值 l ECMAScript变量包含两种不同数据类型的值 ...
- 实战nginx 基础知识总结(一)1.1
squid Squid是一个缓存Internet数据的软件,其接收用户的下载申请,并自动处理所下载的数据.当一个用户想要下载一个主页时,可以向Squid发出一个申请,要Squid代替其进行下载,然后S ...
- USACO March. 2012
Connect the Cows Times17 水题 Landscaping Flowerpot Tractor 广搜 搜到边界就可以终止了 没什么难度 #include <stdio.h&g ...
- python中enumerate 函数
enumerate 函数用于遍历序列中的元素以及它们的下标: >>> for i,j in enumerate(('a','b','c')): print i,j 0 a 1 b ...
- excel unixtime与北京时间互转
unixtime转北京时间,在单元格内输入:=INT((B2-70*365-19)*86400-8*3600) *.要设置一下单元格格式为y-m-d h:m:s才会正确显示 北京时间转unixti ...
- line
小君童靴说头儿给了他一个project,实现给出屏幕上任意两个点,求出这两个点之间直线上的所有的点.觉得这个很好玩,就自己也写了一点code /* date : 2014/10/21 version ...
- Android灭亡论之Firefox OS操作系统出现
今天是2014年7月1日,过几天就要到深圳实训去了,实训核心内容是Android开发.尽管Android现在很火,但作为程序猿的我们必须时刻保持清醒的头脑.我虽不是什么预言家,但近期接触的Androi ...
- java socket线程通信
关于socket线程通信的一些知识整理 一般我们需要要让两台机子进行通信,需要创建一个Server 类,一个Client类,还需要创建一个线程类 server public class Server ...
- arm: 使用结构体操作寄存器
使用结构体操作寄存器: //寄存器赋值和取值的时候,要注意寄存器的长度,有的寄存器的值只有8位. //还要注意,使用volatile修饰寄存器变量.volatile 参考http://www.cnbl ...