2017-06-07 35 views
0

考慮:當使用ASIO + SSL,則ASYNC_WRITE不發送數據

asio::ssl::stream<asio::ip::tcp::socket&> &m_socket; 
async_write(self->m_socket, asio::buffer(self->m_v), 
    [self, handler](asio::error_code ec, std::size_t s) 
{ 
    handler(ec); 
}); 

結果: 發送數據之前調用處理程序(socket.send()函數被調用)。 結果2: 這些數據實際上是在很長一段時間後發送的 - 在我的可重現案例中大約1分鐘。因此,事件的順序如下: 1.調用async_write; 2.處理程序被調用; 3.發送數據。

我認爲正確的順序必須是: 1.調用async_write; 2.發送數據。 3.處理程序被調用;

它不總是發生,但非常重複。我在互聯網上搜索了類似的案例 - 什麼都沒發現。

我需要建議:該怎麼做。這是在asio中的錯誤,還是在我的程序中的一些棘手的錯誤,以及在哪裏尋找修復它。

我可以很容易地重現的情況下,可以提供日誌文件等

+0

如何判斷訂單是否爲1。 2. 3.'而不是'1。 3. 2.'?你的意思是你測量「3.數據收到」而不是「3.數據發送」? – sehe

+0

1.我在日誌消息中添加時間戳。我在async_write之前和處理程序的開始處打印日誌消息。根據這些時間戳我確定1在2之前。至於3,我使用Microsoft Message Analyzer來捕獲網絡流量。消息分析器捕獲還包含時間戳。我相信這些時間戳標記了消息從asio代碼進入網絡系統的時刻。因此,我確信訂單是1. 2. 3. 2.當我寫「3.數據發送」時,我的意思是數據已發送。 – IakovK

+0

如果您在MMA中看到晚於2的時間戳,這並不意味着它在2之後發送(取決於協議中您看到時間戳的位置)。這可能意味着MMA稍後會看到它。此外,像Nagle的算法可能會起作用。 – sehe

回答

0

如果你看到一個時間戳比MMA 2.後來,這並不意味着它得到了2後發送(取決於在協議你看到時間戳)。這可能意味着MMA稍後會看到它。此外,像Nagle的算法可能會起作用。

嘗試設置TCP NODELAY,例如,

socket.open(tcp::v4()); 
socket.set_option(tcp::no_delay(true)); 
socket.async_connect(endpoint, handler); 
+0

我相信MMA會在進入Windows網絡子系統時看到消息,也就是說,當調用socket.send函數時。你能解釋爲什麼我應該相信嗎? – IakovK

+0

由於MMA不在內核中運行,所有進程都相當安排。哪一個獲得下一個時間片的核心是不可預測或固定的 – sehe

+0

在我的設置中,它是微不足道的。如果調度是公平的,每個進程都有機會在幾毫秒內運行。在我的情況下,延遲是50秒左右。毫秒可以忽略不計。 – IakovK

相關問題