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
宏。
待續...