我有一個服務器,它使用一個線程從遠程數據源接收UDP DatagramPackets;和一個TCP ServerSocket來監聽遠程客戶端請求併爲每個客戶端產生一個專用線程。 我想通過ServerSocket將每個DatagramPackets傳輸給多個客戶端。而現在我遇到了重大的數據包丟失。有人可以提供一些建議嗎? 在此先感謝。無阻塞服務器和線程安全
回答
設計中的協議可能只是錯誤的選擇嗎? 對於多個客戶端應該可靠,因爲您使用TCP。但是由於在服務器端引入了對UDP槽耦合(橋接/轉播)的依賴性,可靠性失敗了。
如果考慮到數據包將在設計中丟失,UDP或多或少適用於可靠的應用程序。
- 解決方案1:改變協議
- 解決方案2:如果不可能改變協議,則改變關於服務質量上的客戶端側的用戶的期望
- 解決方案3:添加冗餘到UDP側重複請求,股票數據提前預計未來的質量下降,無論如何維持大量累積的數據緩存以供給客戶端。
4.通過UDP重新實現TCP O.o – 2010-11-12 03:51:16
謝謝您的回答。恐怕這是多線程編程中的一個典型的生產者 - 消費者問題。現在我正在努力。任何指導方針表示讚賞。 – 2010-11-15 09:28:35
這將是更重要的是在發送而不是試圖以某種方式硬塞到你的TCP設計的接收器,它是爲時已晚擺脫UDP 的。數據包在發送者和接收者之間丟失,而不是在你的接收者中。修復接收器代碼不會解決實際問題。
不知道你的應用程序設計的話,我可以做如下的猜測:
- 你的UDP源發送更多的數據包不是你的接收機可以處理造成數據包被丟棄,因爲
- 你的接收器因爲
- 您的TCP客戶端沒有足夠快地拾取數據包導致緩衝區填滿(這會強制服務器阻止導致它丟失UDP數據包的數據包)。
謝謝你的回答。我找到了丟包的原因,就像你說的那樣。接收緩衝區由UDP接收線程和TCP發送線程共享,如果發送線程在新數據包到來之前未完成發送過程,則會導致數據包丟失。我嘗試了wait-notify機制來安排這些寫入和讀取線程,但它很容易死鎖。由於我沒有太多的多線程編程經驗,我不知道是否有其他一些機制。你能提出一些建議嗎?萬分感謝! – 2010-11-15 09:19:55
@Xu DXn:嘗試使用類似[BlockingQueue](http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html)或[ConcurrentLinkedQueue](http ://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html)。每個TCP連接可能有一個隊列。但是您必須處理您接收到的UDP包比一個或多個TCP客戶端可以應付並決定丟棄哪些包的可能性。 – 2010-11-16 22:02:59
- 1. 無狀態阻塞服務器設計
- 2. 非阻塞TCP服務器
- 3. boost :: asio多線程異步接受阻塞讀/寫服務器
- 4. 如何使這個非阻塞服務器成爲多線程?
- 5. 縮放位圖並上傳到服務器,UI線程阻塞
- 6. 阻塞隊列不阻塞線程?
- 7. 阻塞線程 - Java
- 8. Java線程阻塞
- 9. Java線程阻塞
- 10. MessageBeep線程阻塞
- 11. 具有無阻塞或多線程功能的Ruby Tcp服務器類
- 12. 非阻塞線程安全內存池實現
- 13. * nix和C++編寫無阻塞套接字服務器
- 14. BOOST-ASIO阻塞服務器不響應阻塞客戶端?
- 15. 將線程阻塞轉換爲f中的非線程阻塞#
- 16. 線程池與許多阻塞任務
- 17. Nodejs中的無效IP阻塞,節點應用程序安全
- 18. 服務器的非阻塞套接字
- 19. Java服務器非阻塞查詢
- 20. Java套接字服務器阻塞
- 21. 非阻塞服務器Apache Thrift Python
- 22. Socket IO發送服務器阻塞
- 23. 線程執行器非阻塞列表
- 24. Java輸入流「阻塞」和多線程
- 25. 如何阻塞和通知線程
- 26. 使Web請求的Android服務線程阻塞用戶界面
- 27. 在Windows C++服務中阻塞兩個線程
- 28. 在.Net中阻塞線程
- 29. 沒有阻塞線程
- 30. Spring ObjectPooling&線程阻塞
哪裏(在服務器和數據源或服務器和客戶端之間)以及您在哪個方向發生這種嚴重的數據包丟失? – 2010-11-12 03:32:36