2011-06-22 110 views
3

如果我使用close而不是cancel,則會出現一些問題。使用boost :: asio :: ip :: tcp :: socket :: cancel()和socket :: close()

close函數可以關閉套接字,並且任何未完成的異步操作都會通過返回boost::asio::error::operation_aborted錯誤而停止。

爲什麼要用cancel代替close

我擔心如果一些異步操作正在執行,cancel無法取消它,是嗎?

asio::ip::tcp::resolve::cancel,我嘗試了很多次調用async_resolve後取消resolve_handler,但resolve_handler始終沒有boost::asio::error::operation_aborted返回錯誤。

我認爲resolve_handler正在執行?

是嗎?

回答

6

如果您希望在不關閉套接字的情況下停止掛起的操作,那麼取消很有用。

注意,Boost documentation建議使用接近更便於攜帶(DOC從頁):

... 對於便攜式消除,考慮 使用以下 選項之一:

  • 通過定義 BOOST_ASIO_DISABLE_IOCP來禁用asio的I/O完成端口 後端。
  • 使用 close()函數可以同時取消 的優秀操作和關閉插座 。
+1

但請注意cancel()的註釋也爲*在Windows Vista,Windows Server 2008及更高版本上運行時,始終使用CancelIoEx函數。 * –

+0

感謝你和Sam Miller的幫助,我現在明白了一點,謝謝 –

6

cancel不會關閉套接字,所以使用cancel,如果你想繼續使用Socket對象。特別是,如果在引用套接字成員函數的異步處理程序方法中有代碼,則可能不希望關閉套接字,直到確保當前正在執行的異步處理程序已完成。

cancel不保證任何有關當前正在執行的異步處理程序,它只能保證(每升壓文檔)說:「該功能將導致所有未完成的異步連接,發送和接收操作立即完成」的socket::cancel()呼叫的情況,或者在調用resolver::cancel()的情況下,「此函數強制完成主機解析器上的任何未決異步操作」。這個「完成」意味着boost將調用你的異步處理方法,它沒有管轄權將任何取消邏輯注入異步處理程序(更不用說它不知道處理程序的實現開始)。

我會建議添加自己的邏輯到你的異步處理方法來處理socket/resolver/etc等情況。被取消。如果您正在調用cancel方法,那麼您可能有能力將此取消操作傳遞給異步處理程序方法。

+0

holtavolt是正確的,使用close()更具可移植性,但這一切都取決於你是什麼試圖去做。 – devyndraen

+0

感謝您的幫助,是的,我創建了serveral對象來處理http請求,並將這些對象放入std :: deque,一個任務到來,pop_front從deque到一個對象的一個​​對象,完成push_back對象到deque時,錯誤在連接,發送或讀取,我會關閉套接字,但在連接和讀取,我設置20秒超時,當連接超時,我想取消回調func handle_connect,在這個handle_connect_timeout或handle_read_timeout,我不知道哪一個使用,取消或關閉,但現在,我認爲對我來說最好的一個很接近 –

相關問題