asio boost 异步错误处理_c-Boost :: Asio异步写入失败

本文介绍了在使用Boost ASIO进行异步写入时遇到的错误,即由于忘记保存套接字实例的引用导致的operation_aborted错误。通过两种方法修复这个问题:1) 使用shared_ptr保持套接字引用;2) 利用enable_shared_from_this进行会话管理。示例代码展示了如何应用这些修复方法。
摘要由CSDN通过智能技术生成

在您的async_write_some调用上,您忘记保存对套接字实例的引用.

这将导致套接字对象被破坏,并且作为析构函数的一部分,所有挂起的异步操作都将被取消.这说明您收到ec operation_aborted.

通过将套接字指针添加到绑定的参数来修复它,或者将enable_shared_from_this惯用法与CSession类型一起使用.

使用更多shared_pointer魔术:

这是“最简单的”编辑:

void write_handler(

boost::shared_ptr<:string> pstr,

boost::shared_ptr<:socket> /*keepalive!*/,

error_code ec, size_t bytes_transferred)

{

if(ec)

std::cout<< "Failed to send! " << boost::system::system_error(ec).what() << "

";

else

std::cout<< *pstr << " has been sent (" << bytes_transferred << " bytes transferred)

";

}

应该绑定如下:

psocket->async_write_some(ba::buffer(*pstr),

boost::bind(&CService::write_handler, this, pstr, psocket,

ba::placeholders::error, ba::placeholders::bytes_transferred));

几项风格改进

>不使用名称空间

>使用asio占位符(不是_1,_2)

打印:

g++ -std=c++11 -O2 -Wall -pedantic main.cpp -pthread -lboost_system -lboost_filesystem && ./a.out& while sleep .1; do nc 127.0.0.1 6767; done

127.0.0.1

hello async world!hello async world! has been sent (18 bytes transferred)

127.0.0.1

hello async world!hello async world! has been sent (18 bytes transferred)

127.0.0.1

hello async world!hello async world! has been sent (18 bytes transferred)

...

使用CSession(enable_shared_from_this)

这是另一个习惯用法,它避免拼出所有共享指针.

不必保留指向套接字和缓冲区的明确的共享指针,而是使一个类包含这两者:

struct CSession : boost::enable_shared_from_this {

CSession(ba::io_service &iosev)

:m_iosev(iosev), m_sock(m_iosev)

{}

void do_response();

private:

void write_handler(error_code ec, size_t bytes_transferred);

ba::io_service &m_iosev;

tcp::socket m_sock;

std::string response;

};

现在绑定看起来像:

boost::bind(&CSession::write_handler,

shared_from_this(), /* keep-alive! */

ba::placeholders::error, ba::placeholders::bytes_transferred)

简单得多.会话管理是CService的职责,就像以前一样:

void start()

{

auto session = boost::make_shared(m_iosev);

m_acceptor.async_accept(session->m_sock,

boost::bind(&CService::accept_handler, this, session, ba::placeholders::error));

}

void accept_handler(boost::shared_ptr session, error_code ec) {

if(ec) {

std::cerr << "Accept failed: " << ec.message() << "

";

} else {

session->do_response();

start();

}

}

#include

#include

#include

#include

#include

#include

namespace ba = boost::asio;

using boost::system::error_code;

using ba::ip::tcp;

namespace HelloWorld {

struct CSession : boost::enable_shared_from_this {

CSession(ba::io_service &iosev)

:m_iosev(iosev), m_sock(m_iosev)

{}

void do_response() {

response = "hello async world!

";

std::cout << m_sock.remote_endpoint().address() << std::endl;

m_sock.async_write_some(ba::buffer(response),

boost::bind(&CSession::write_handler,

shared_from_this(), /* keep-alive! */

ba::placeholders::error, ba::placeholders::bytes_transferred));

}

private:

void write_handler(error_code ec, size_t bytes_transferred)

{

if(ec)

std::cout<< "Failed to send! " << boost::system::system_error(ec).what() << "

";

else

std::cout<< response << " has been sent (" << bytes_transferred << " bytes transferred)

";

}

ba::io_service &m_iosev;

friend class CService;

tcp::socket m_sock;

std::string response;

};

struct CService

{

CService(ba::io_service &iosev)

:m_iosev(iosev),m_acceptor(iosev, tcp::endpoint(tcp::v4(), 6767))

{}

void start() {

auto session = boost::make_shared(m_iosev);

m_acceptor.async_accept(session->m_sock,

boost::bind(&CService::accept_handler, this, session, ba::placeholders::error));

}

void accept_handler(boost::shared_ptr session, error_code ec) {

if(ec) {

std::cerr << "Accept failed: " << ec.message() << "

";

} else {

session->do_response();

start();

}

}

private:

ba::io_service &m_iosev;

tcp::acceptor m_acceptor;

};

}

int main() {

ba::io_service iosev;

using namespace HelloWorld;

CService sev(iosev);

sev.start();

iosev.run();

}

具有相似的输出.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值