千家信息网

boost async_read_some 用法

发表于:2024-11-16 作者:千家信息网编辑
千家信息网最后更新 2024年11月16日,async_read_some读到数据就会直接回调设置的函数,不管数据是否已经读完。所以在这里会遇到一个非常棘手的问题,如何确定数据已经读取完毕?常见的方式是在数据的后面添加标志位,例如添加/r/n/
千家信息网最后更新 2024年11月16日boost async_read_some 用法

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

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

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

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

不应该被调用


class CSession : public boost::enable_shared_from_this

{

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 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;

};


注意

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


数据 函数 客户 客户端 时候 标志 消息 线程 棘手 事情 代表 任务 例子 原因 原理 参数 常见 方式 是在 服务器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 魔兽世界正式服务器和职业 河北网络技术服务电话多少 软件开发只会一点基础 天涯明月刀哪个数据库 买的云服务器与虚拟机区别 长宁区网络软件开发机构整顿 派出所网络安全知识培训 海南高校网络安全研讨会 江西宽带网络技术有限公司 腾讯云服务器需要更新吗 软件开发工具选择题 软件开发关键控制点 数据库汇总两个表格数据表 关于网络安全的题目以及答案 服务器配件公司 辽宁省网络安全考试题答案 统战干部加强网络安全管理 俄罗斯网络安全有多重要 南通极道网络技术有限公司 访问不了别人oracle数据库 软件开发只会一点基础 了解常用的软件开发方法 网站数据库是不是data 游戏软件开发排行榜 河北前端软件开发哪家好 青岛分销软件开发哪家靠谱 数据库act功能 网络安全主要负责人职责 服务器装机后如何恢复出厂设置 旺庄街道代办网络技术工作室
0