2010-03-03 19 views
3

在下面的代码:是否可以在boost.ASIO中使用asyn_read来销毁套接字对象?

tcp::socket socket(io_service); 
tcp::endpoint ep(boost::asio::ip::address::from_string(addr), i); 


socket.async_connect(ep, &connect_handler); 

socket.close(); 

是正确关闭套接字对象,或者我应该关闭它只有在connect_handler(),度假村到shared_ptr延长的Socket对象的生活吗? 谢谢。

回答

3

关闭套接字是没有太大问题的,但插座被破坏和释放是。解决这个问题的一个方法就是确保套接字胜过正在完成工作的io_service。换句话说,你只要确保在io_service退出之前不要删除它。显然这不适用于任何情况。

在各种各样的情况下,当它在io_service中处于活动状态时,如果所有工作都是在socket上完成的,并且ASIO不提供任何明确移除或断开对象回调的机制,他们不会被叫到。所以你应该考虑把连接保存在一个shared_ptr中,它将保持连接对象直到io_service中的最后一个引用被释放。

同时处理程序函子应该处理通过在所有可能的错误,包括被破坏的连接。

+0

感谢您的回答,特别是。这一行:“关闭套接字不是一个问题,但套接字被破坏和释放是”。有时候你只需要有人指出一件小事,而其他一切似乎都很明显。情况就是如此。 – 2010-03-26 04:12:52

1

它是安全的。 connect_handler会给你ec == boost :: asio :: error :: connection_aborted。当然,你需要为处理程序调用io_service.run()。

+0

谢谢,是不是说,当涉及到asyn_ *操作时,你几乎总是需要动态创建一个套接字(使用shared_prt 来延长它的生命周期),以便它不会因为对象超出范围而关闭? – 2010-03-11 08:56:21

1

正如已经吃辣的回答,就可以安全地关闭,只要你想的插座。如果有问题的套接字当时有未完成的操作,则会调用处理程序/回调以通知您已取消该操作。这就是connection_aborted出现的地方。

至于你提到的shared_ptr的问题,我认为这是一个巨大的胜利,如果你有另一个线程或其他对象引用您的插座,但是,它不是在许多情况下需要。您只需动态分配它们,并在不再需要时释放它们。当然,如果你有其他的对象或线程引用你的套接字,你必须在删除/ dealloc之前更新它们。这样做可以避免无效的内存访问,因为它们指向的对象不再存在(请参阅悬挂指针)。

+0

谢谢你的回应,它确实回答我的问题。不幸的是,我只能接受一个答案。 – 2010-03-26 04:15:57

相关问题