2010-03-03 18 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

相關問題