我正在開發一個應用程序,通過UDP(1036字節數據報大小)接收高達900 Mb/s的數據。在「正常」環境下(沒有系統負載和用戶交互),一切正常:操作系統或應用程序不報告丟棄的數據報。當我開始點擊Windows資源管理器的文件夾樹時,更改其主顯示窗格的內容時,數據報將被刪除。我通過使用Windows性能監視器並檢查數據報有效負載中烘焙的序列號來觀察此情況。 對於每次點擊,都會丟失數百個數據報。操作Windows資源管理器窗口時UDP數據包丟失
接收緩衝區大小增加(128 MB操作系統,甚至更多用於我的應用程序)。我進一步觀察到,如果調用
ioctlsocket(my_socket, FIONREAD, &readableBytes);
返回精確的字節數,則沒有緩衝區達到其極限。最高觀察值低於2 MB。 我不確定哪些其他緩衝區可能會溢出以及如何跟蹤其狀態。
該應用程序是使用Qt開發的。除了UDP接收線程之外,還有三個線程正在使用中。當沒有用戶交互並且接收線程被切斷時,它們都是空閒的。所有這些都是重現問題的每個測試設置的情況。
接收線程的第一次迭代使用Qt UDP套接字,並檢查正確的序列號。
第二次迭代使用普通的WinSock調用recv(...),檢查另一個線程完成的序列號。這顯然增加了線程數量。這兩個線程都通過一個無鎖隊列進行通信,這個隊列完全能夠處理呈現給它的讀寫操作。儘管如此,即使只有接收者線程正在運行(讀取數據報並丟棄它們),也可以觀察到與上述相同的行爲。
即使是具有多個接收者線程的實現(也只能讀取和丟棄)顯示相同的行爲。
即使數據速率下降到330 Mb/s,但仍然不太頻繁,可能會出現問題。它以更低的數據速率消失。
是的我知道UDP不能保證傳送,但數據包明顯到達我的機器,並被充足的CPU時間和緩衝區空間丟棄 - 這似乎很奇怪,至少可以說。
我想知道:
- 是否有此行爲的任何解釋?
- 如果是這樣,有什麼可能的解決方案?
- 如果沒有,可以通過檢查找出導致此問題的原因?
任何幫助或方向遵循將不勝感激,謝謝!
UDP可用於任何數據,而不僅僅是_current data_。例如,洪流協議使用它進行傳輸,根據定義,它沒有_current data_。 –
我可能循環地使用「current」來表示那些並不比最近到達的數據包差。假設是數據包以固定速率到達。如果是這樣,接收緩衝區填充顯然是由於接收代碼無法應付數據速率。保留這些數據包沒有意義,隊列只會增長,所以它們必須被丟棄。 2MB在千兆位鏈路上的值爲22ms。 –
感謝您的回答!我假設你的意思是在重疊的I/O模式下使用WSARecv。 –