ASIO库使用注意事项

1. 使用 io_service::work 实现 io_service 无任务时不退出

正常情况下向io_service抛任务,它执行完成后就会自动退出,而要实现那种chromium那种的循环队列,没有任务就等待任务的效果,可以使用io_service初始化一个 io_service::work ,只要这个work没有被析构,那么service就不会主动结束。

但是在要销毁service时,要想让它完全退出,需要先将work销毁,再等待service内还在执行的任务执行完成,service才能完全结束。

写asio程序最容易碰到的就是程序无法结束,根源就在于使用的io_service一直没有结束。未超时的timer、还在活跃中的socket等,都需要手动结束或释放,service才能正常退出。

2.指定网卡加入组播

服务端:

asio::ip::udp::endpoint listenEndpoint(asio::ip::udp::v4(), _multiCastPort);
_listenSocket.open(listenEndpoint.protocol());

_listenSocket.set_option(asio::ip::udp::socket::reuse_address(true));
_listenSocket.set_option(asio::ip::multicast::enable_loopback(true));
    //绑定网卡,加入组播组
    asio::ip::udp::endpoint localEndpoint(asio::ip::address_v4::from_string(_interfaceIp), _multiCastPort);
    asio::ip::udp::endpoint multiCastEndpoint(asio::ip::address_v4::from_string(_multiCastIp), _multiCastPort);
    _listenSocket.set_option(asio::ip::multicast::join_group(
        multiCastEndpoint.address().to_v4(), localEndpoint.address().to_v4()));

发送端:

// 绑定网卡地址
  asio::ip::address_v4 local_interface =
      asio::ip::address_v4::from_string(_interfaceIp);
  asio::ip::multicast::outbound_interface option(local_interface);

sendSocket->set_option(option);

3. async_send_to等异步操作最好自己保留现场

这些异步操作很可能会在你当前对象已经被销毁的情况回调,从而导致空指针错误。要避免这种问题,就是尽量在回调中不用this指针,也就是不用对象的普通成员函数和变量。需要的数据可以使用shared_ptr等智能指针或者直接值拷贝的方式传递到回调函数中。当然如果你能保证你的所有异步回调都会在对象释放前执行,那就可以不用这么干。

4. 不依赖boost使用asio

asio可以脱离boost单独使用,需要设置ASIO_STANDALONE宏。

待续...

原文地址:https://www.cnblogs.com/xl2432/p/11362123.html