文档章节

Boost asio的async_write函数输入日志标题

雅各宾
 雅各宾
发布于 2014/08/06 14:52
字数 610
阅读 92
收藏 0

Boost asio是一个异步网络通信的库,其中async_write是一个比较常用的函数,但是,如果没有正确的使用,就可能会出现一些意想不到的潜在Bug。例如下面的代码:

   1:  for (int i=0; i < n; i++)

   2:  {

   3:      boost::asio::async_write(

   4:          socket_,

   5:          boost::asio::buffer( buffer[i].data_.get(), buffer[i].length_ ),

   6:          boost::asio::transfer_at_least(buffer[i].length_),

   7:          boost::bind(

   8:              &HttpServer::HandleTcpSend,

   9:              shared_from_this(),

  10:              boost::asio::placeholders::error,

  11:              boost::asio::placeholders::bytes_transferred

  12:          )

  13:      );

  14:      // Do something

  15:  }

 

代码很简单,就是循环N次,发送N块buffer。我们的目标是,接收端依次接收buffer1,buffer2,……,buffer n。但是,事实上,上面的代码是有问题的,服务器可能会接收到完全错乱的数据。先看一下正确的写法,代码如下:

   1:  int i=0;

   2:  boost::asio::async_write(

   3:      socket_,

   4:      boost::asio::buffer( buffer[i].data_.get(), buffer[i].length_ ),

   5:      boost::asio::transfer_at_least(buffer[i].length_),

   6:      boost::bind(

   7:          &HttpServer::HandleTcpSend,

   8:          shared_from_this(),

   9:          boost::asio::placeholders::error,

  10:          boost::asio::placeholders::bytes_transferred

  11:      )

  12:  );

  13:  &#160;

  14:  // Do something

  15:

  16:  void HttpServer::HandleTcpSend(const boost::system::error_code& err,

  17:      size_t bytes_transferred)

  18:  {

  19:      i++;

  20:      boost::asio::async_write(

  21:          socket_,

  22:          boost::asio::buffer( buffer[i].data_.get(), buffer[i].length_ ),

  23:          boost::asio::transfer_at_least(buffer[i].length_),

  24:          boost::bind(

  25:              &HttpServer::HandleTcpSend,

  26:              shared_from_this(),

  27:              boost::asio::placeholders::error,

  28:              boost::asio::placeholders::bytes_transferred

  29:          )

  30:      );

  31:  }

 

也就是在第一个buffer发成功之后,再发送第二个buffer,依次类推。为什么一定要这样写呢?首先,看一下async_write是怎么实现的,aysnc_write里面调用async_write_some函数。也就是说,async_write一次数据发送,并一定把所有的数据都发送完,有可能async_write一次就发其中的一部分。那么,如果在第一个async_write还没有发送完毕之后,从第二个async_write发送数据,势必导致接收端接收的数据有问题。这个并不是asio的限制,底层套接字的一些函数,如发送等也无法保证一次异步操作就把所有的数据都通过TCP流发送出去。async_write将被告知有多少字节实际发送了,然后要求在下一次异步操作时发送剩余的字节。async_write是通过一次或者多次调用async_write_some函数来实现的,那么如果在第一个async_write还没有完成就调用第二个async_write,async_write_some就有可能先将第二个buffer的数据先发送出去。

因此,NEVER start your second async_write before the first has completed.

本文转载自:http://blog.sina.com.cn/s/blog_9e7299ff01017ax1.html

雅各宾
粉丝 9
博文 125
码字总数 53022
作品 0
深圳
技术主管
私信 提问
Boost.Asio技术文档

Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE10.txt文件或从http://www.boost.org/LICENSE1_0.txt) Boost.Asio是用......

LUIS1983
2016/12/23
259
0
boost------asio库的使用2(Boost程序库完全开发指南)读书笔记

网络通信 asio库支持TCP、UDP、ICMP通信协议,它在名字空间boost::asio::ip里提供了大量的网络通信方面的函数和类,很好地封装了原始的Berkeley Socket Api,展现给asio用户一个方便易用且健...

LUIS1983
2016/12/23
66
0
Boost ASIO proactor 浅析

Boost ASIO proactor 浅析 前情提要: Boost asio 的socket的异步非阻塞模式才有的是proactor模式,当IO操作介绍后回调相应的处理函数。ASIO在Linux平台下的实现基于epoll,但是epoll只支持r...

晨曦之光
2012/06/07
653
0
boost::asio::buffer() 在BOOST SOCKET 中写时是否多做了一次拷贝?

我们在使用BOOST SOCKET 时,当在一个连接上写数据时,总是将要写的字节流通过boost::asio::buffer() 封装起来然后将返回值做为参数传递给写函数(比如:boost::asio::async_write())。 但是...

su_yh
2016/05/03
453
1
C++网络和IO开发包--Asio

Asio 是一个跨平台的C++开发包用来处理网络和低级I/O编程,通过先进的C++方法为开发人员提供连续异步模型。 示例代码: void handleread(const asio::errorcode& error, sizet bytestransfe...

匿名
2010/05/28
16.2K
0

没有更多内容

加载失败,请刷新页面

加载更多

为什么要在网站中应用CDN加速?

1. 网页加载速度更快 在网站中使用CDN技术最直接的一个好处就是它可以加快网页的加载速度。首先,CDN加速的内容分发是基于服务器缓存的,由于CDN中缓存了不少数据,它能够给用户提供更快的页...

云漫网络Ruan
24分钟前
2
0
亚玛芬体育(Amer Sports)和信必优正式启动合作开发Movesense创新

亚玛芬体育和信必优正式启动合作开发Movesense创新,作为亚玛芬体育的完美技术搭档,信必优利用Movesense传感器技术为第三方开发移动应用和服务。 Movesense基于传感器技术和开放的API,测量...

symbiochina88
35分钟前
2
0
创龙TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA核心板规格书

SOM-TL437xF是一款广州创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA芯片设计的核心板,采用沉金无铅工艺的10层板设计,适用于高速数据采集和处理系统、汽车导航、工业自动化等领...

Tronlong创龙
36分钟前
2
0
好程序员Java学习路线分享MyBatis之线程优化

  好程序员Java学习路线分享MyBatis之线程优化,我们的项目存在大量用户同时访问的情况,那么就会出现大量线程并发访问数据库,这样会带来线程同步问题,本章我们将讨论MyBatis的线程同步问...

好程序员官方
42分钟前
6
0
IDEA 自定义方法注解模板

IDEA 自定义方法注解模板 1、使用效果 /*** 计算交易费用* @Author wangjiafang* @Date 2019/9/11* @param feeComputeVo* @return*/@PostMapping("/v1/fee_compute")public ApiResp......

小白的成长
42分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部