簡體   English   中英

使用Boost.Asio強制異步套接字讀取盡早完成

[英]Force asynchronous socket read to finish early using Boost.Asio

我有一個tcp::socket用於讀取和寫入數據。 通過鏈接async_read_some()和處理程序on_data_read()組成一個讀取循環,該處理程序在處理讀取的數據后再次調用async_read_some() 相關的shared_ptr<tcp::socket>沿着循環傳遞。 當循環結束on_data_read()是帶一個非成功error_codeasio::error::eof ,在這種情況下async_read_some()不被調用。

套接字上可能還會有異步寫入,這是通過重復調用async_write_some()直到寫入所有數據來完成的。 也就是說,處理程序on_data_written()async_write_some()調用async_write_some()如果再次將數據僅部分寫入。 相關的shared_ptr<tcp::socket>也沿調用鏈傳遞。

現在,我想以安全的方式關閉插座。 具體來說,我想用一個不成功的錯誤代碼來強制異步讀取盡早結束讀取循環。 如果沒有掛起的寫調用鏈,則唯一的shared_ptr<tcp::socket> (沿着讀取循環傳遞的那個)將被關閉,並且其托管的tcp::socket被銷毀。 如果有一個掛起的寫調用鏈,它會一直持續到所有數據都寫完為止。 在寫調用鏈結束時,最后一個shared_ptr<tcp::socket> (沿着寫調用鏈傳遞的那個)被破壞了。 從某種意義上說,此過程是安全的,因為套接字在掛起的寫入(如果有)之后被關閉。

問題是

  • 我該如何強制異步套接字讀取以不成功的錯誤代碼結束?

我已經檢查了纏綿選項。 但這不起作用,因為我使用的是鏈式async_write_some()而不是單個async_write() 因此,可以在on_data_written()關閉套接字。 cancel()close()也不起作用,因為它們不僅中斷讀取循環,而且中斷寫入調用鏈。 而且,盡管shutdown()可應用於讀取循環,但它僅阻止將來的async_read_some()調用,並且對已完成的操作沒有影響。 我已經制定了一種解決方法。 也就是說,調用cancel() ,但是讓on_data_written()忽略由cancel()引起的錯誤代碼,並繼續執行寫調用鏈。 我對這種解決方案不滿意(請參閱此處的備注部分)。 我想知道是否有更直接,更優雅的方式來實現我想要的功能,或者整個設計存在缺陷?

我認為您已經很好地總結了這一點。

你真的不能做得比完全取消更好。 實際上,您可以恢復所有取消的寫入。

我認為沒有什么比這更優雅的了。 我不會說設計有缺陷,但是您可能要考慮不實際取消掛起的操作,而只是保留一個標志以指示“邏輯讀取取消”是否掛起並在這種情況下防止鏈接更多讀取

當您使用shutdown ..... socket.shutdown時,您是否使用了shutdown_both?

(boost :: asio :: ip :: tcp :: socket :: shutdown_both,ec)

shutdown_both選項。 那應該處理讀寫閉包。

socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
if (errorcode)
{
    cerr << "socket.shutdown error: " << errorcode.message() << endl;
}

另外,如果您具有io_service句柄。 您可以最后調用io_service.stop(),這將關閉所有操作。

關閉插座進行輸入。 這將導致所有掛起的讀取遇到流的末尾並相應地返回。

而且,盡管shutdown()僅可應用於讀取循環,但它僅阻止將來的async_read_some()調用,並且對已完成的操作沒有影響。

我不知道你從哪里得到這個錯誤信息。 我什至不知道這意味着什么。 關機適用於套接字,而不適用於讀取循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM