博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
boost async_read_some 用法
阅读量:6069 次
发布时间:2019-06-20

本文共 2153 字,大约阅读时间需要 7 分钟。

async_read_some读到数据就会直接回调设置的函数,不管数据是否已经读完。所以在这里

会遇到一个非常棘手的问题,如何确定数据已经读取完毕?常见的方式是在数据的后面添加

标志位,例如添加/r/n/r/n作为结束符,然后停止读取

async_read_some的基本原理是往IOCP的队列里面添加一个异步任务,没有事情的时候,CSession::ContinueRead

不应该被调用

class CSession : public boost::enable_shared_from_this<CSession>

{

public:

CSession(boost::asio::io_service &io_service) : m_socket(io_service)

{

memset(m_szRecvBuffer, 0x00, 1024);

m_bStartRecv = false;

}

void Start()

{

static boost::asio::ip::tcp::no_delay option(true);

m_socket.set_option(option);

boost::function0<void> f = boost::bind(&CSession::StartThread, this);

boost::thread thrd(f);

}

/*

启动线程函数的根本原因是需要向客户端推送消息,而且在过程中需要等待接收消息

*/

void StartThread()

{

while (true)

{

/*

使用m_bStartRecv标志位主要是为了避免多次设置回调,当正在接收的时候,不需要设置回调

*/

if (!m_bStartRecv)

{

m_bStartRecv = true;

m_socket.async_read_some(boost::asio::buffer(m_szRecvBuffer),

boost::bind(&CSession::ContinueRead, shared_from_this(),

boost::asio::placeholders::error,

boost::asio::placeholders::bytes_transferred));

}

char szAlarm[32] = "alarm";

boost::system::error_code ec;

m_socket.send(boost::asio::buffer(szAlarm), 0, ec);

boost::this_thread::sleep_for(boost::chrono::milliseconds(3000));

if (ec) break;

}

}

private:

/*

在当前接收回调函数中,我们还继续设置了回调函数m_socket.async_read_some,避免仅仅是读取数据包的一部分,

在这里m_szRecvBuffer会一直作为接收的缓冲,而之前接收的数据也在里面,并且剩下的数据,会根据偏移量,填充到

m_szRecvBuffer的后面,bytes_transferred参数代表当前已经接收的数据

*/

void ContinueRead(const boost::system::error_code &error, std::size_t bytes_transferred)

{

if (error) return;

m_strMatch = m_strMatch + m_szRecvBuffer;

int index = m_strMatch.find("\r\n\r\n", 0);

if (-1 != index)

{

int ret = m_socket.send(boost::asio::buffer(m_szRecvBuffer));

std::cout << m_szRecvBuffer << std::endl;

m_bStartRecv = false;

return;

}

m_socket.async_read_some(boost::asio::buffer((m_szRecvBuffer)),

boost::bind(&CSession::ContinueRead, shared_from_this(),

boost::asio::placeholders::error,

boost::asio::placeholders::bytes_transferred));

}

private:

boost::asio::ip::tcp::socket m_socket;

char m_szRecvBuffer[1024];

std::string m_strMatch;

bool m_bStartRecv;

};

注意

当前的仅仅是一个例子,并没有考虑到客户端关闭连接,服务器线程及时退出

     本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1954436,如需转载请自行联系原作者
你可能感兴趣的文章
开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
查看>>
开源磁盘加密软件VeraCrypt教程
查看>>
本地vs云:大数据厮杀的最终幸存者会是谁?
查看>>
阿里云公共镜像、自定义镜像、共享镜像和镜像市场的区别 ...
查看>>
shadowtunnel v1.7 发布:新增上级负载均衡支持独立密码
查看>>
Java线程:什么是线程
查看>>
mysql5.7 创建一个超级管理员
查看>>
【框架整合】Maven-SpringMVC3.X+Spring3.X+MyBatis3-日志、JSON解析、表关联查询等均已配置好...
查看>>
要想成为高级Java程序员需要具备哪些知识呢?
查看>>
带着问题去学习--Nginx配置解析(一)
查看>>
onix-文件系统
查看>>
java.io.Serializable浅析
查看>>
我的友情链接
查看>>
多线程之线程池任务管理通用模板
查看>>
CSS3让长单词与URL地址自动换行——word-wrap属性
查看>>
CodeForces 580B Kefa and Company
查看>>
开发规范浅谈
查看>>
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
查看>>
鼠标增强软件StrokeIt使用方法
查看>>
本地连接linux虚拟机的方法
查看>>