2015-07-09 77 views
2

試着瞭解boost asio庫,我實現了一個異步回顯服務器。我要求tcp::socket爲少量數據做一個async_read_some,即9個字節(選擇測試爲一個小數字),即socket_.async_read_some(boost::asio::buffer(buf, 9), callback)。然後,我將少量數據提供給服務器,並且讀取命令只有在完整的9個字節才能讀取時回調,而不是在寫入後立即寫入,例如4個字節,正如我所料。什麼決定了什麼時候回調發生,以及爲什麼一旦有一些數據在套接字上可用就不會發生?什麼時候升壓asio調用async_read_some回調?

+0

當操作系統發出數據可用時,確實會發生這種情況。這很大程度上取決於硬件緩衝區,IRQ級別等。它基本上是實現定義的。 – sehe

+0

@sehe因此,如果我使用'asyn_read_some',那麼對於boost調用我就沒有​​什麼不同了?即當套接字打開並且有數據要被讀取時,我可能永遠不會被回調? –

+0

您可以調整sysctls和驅動程序參數。也許你可以使用特定的硬件。您可以在發送端禁用[Nagle算法](https://en.wikipedia.org/wiki/Nagle's_algorithm)。您可以確保沒有路由設備重新排列數據包等。 – sehe

回答

2

socket.async_read_some()操作具有與其同步對應操作socket.read_some()相同的完成條件。

  • 一個或多個數據字節已被成功接收
  • 時發生的錯誤,將防止從正在接收

一旦操作完成(成功數據:當任一操作被認爲是完整的或失敗),則ReadHandler將被髮布到io_service中用於延期調用。此時,ReadHandler可以由服務於io_service的任何線程調用。


當數據的少量正被寫入的插座,如在問題描述,一個典型地觀察到沒有被髮送,直到隨後的數據被寫入到由於Nagle's algorithm插座數據的行爲。簡而言之,許多系統將嘗試通過將小出站消息連接成單個消息來緩解IP/TCP擁塞,然後發送該消息。爲了顯式地禁用上的每個套接字這個問題,設置boost::asio::ip::tcp::no_delay選項:

boost::asio::ip::tcp::socket socket(io_service); 
// ... 
boost::asio::ip::tcp::no_delay option(true); 
socket.set_option(option); 

有疑問時,監測電線流量與分組分析器,如Wireshark的或tcpdump的,在發送器和接收器兩者。通常可以使用這些工具快速確定問題是發送方還是接收方。在識別違規端時,通常需要深入到內核,驅動程序或硬件文檔中,以確定可能成爲問題根源的配置。

相關問題