轉載自:http://hi.baidu.com/gamedot/item/96cb9bf1a717eb14d6ff8cd5面試
最近在作一個項目,在這以前,作了個驗證程序.
發現客戶端連續發來1000個1024字節的包,服務器端出現了丟包現象.
糾其緣由,是服務端在還未徹底處理掉數據,客戶端已經數據發送完畢且關閉了.
有沒有成熟的解決方案來解決這個問題.
我用過sleep(1),暫時解決這個問題,可是這不是根本解決辦法,若是數據量大而多,網絡狀況不太好的話,仍是有可能丟失.算法
你試着用阻塞模式吧...
select...我開始的時候好像也遇到過..不過改成阻塞模式後就沒這個問題了...編程
採用回包機制,每一個發包必須收到回包後再發下一個緩存
UDP丟包是正常現象,由於它是不安全的。安全
丟包的緣由我想並非「服務端在還未徹底處理掉數據,客戶端已經數據發送完畢且關閉了」,而是服務器端的socket接收緩存滿了(udp沒有流量控制,所以發送速度比接收速度快,很容易出現這種狀況),而後系統就會將後來收到的包丟棄。你能夠嘗試用setsockopt()將接收緩存(SO_RCVBUF)加大看看能不能解決問題。服務器
服務端採用多線程pthread接包處理網絡
UDP是無鏈接的,面向消息的數據傳輸協議,與TCP相比,有兩個致命的缺點,一是數據包容易丟失,二是數據包無序。
要實現文件的可靠傳輸,就必須在上層對數據丟包和亂序做特殊處理,必需要有要有丟包重發機制和超時機制。
常見的可靠傳輸算法有模擬TCP協議,重發請求(ARQ)協議,它又可分爲連續ARQ協議、選擇重發ARQ協議、滑動窗口協議等等。
若是隻是小規模程序,也能夠本身實現丟包處理,原理基本上就是給文件分塊,每一個數據包的頭部添加一個惟一標識序號的ID值,當接收的包頭部ID不是指望中的ID號,則斷定丟包,將丟包ID發回服務端,服務器端接到丟包響應則重發丟失的數據包。
模擬TCP協議也相對簡單,3次握手的思想對丟包處理頗有幫助。多線程
udp是不安全的,若是不加任何控制,不只會丟失包,還可能收到包的順序和發送包的順序不同。這個必須在本身程序中加以控制才行。
收到包後,要返回一個應答,若是發送端在必定時間內沒有收到應答,則要重發。socket
UDP原本存在丟包現象,如今的解決方案暫時考慮雙方增長握手.
這樣作起來,就是UDP協議裏面加上了TCP的實現方法.
程序中採用的是pthread處理,丟包率時大時小,不穩定可靠性能
我感受緣由可能有兩個,一個是客戶端發送過快,網絡情況很差或者超過服務器接收速度,就會丟包。
第二個緣由是服務器收到包後,還要進行一些處理,而這段時間客戶端發送的包沒有去收,形成丟包。
解決方法,一個是客戶端下降發送速度,能夠等待回包,或者加一些延遲。
二是,服務器部分單獨開一個線程,去接收UDP數據,存放在一個緩衝區中,又另外的線程去處理收到的數據,儘可能減小由於處理數據延時形成的丟包。
有兩種方法解決樓主的問題:
方法一:從新設計一下協議,增長接收確認超時重發。(推薦)
方法二:在接收方,將通訊和處理分開,增長個應用緩衝區;若是有須要增長接收socket的系統緩衝區。(本方法不能從根本解決問題,只能改善)
網絡丟包,是再正常不過的了。
既然用UDP,就要接受丟包的現實,不然請用TCP。
若是必須使用UDP,並且丟包又是不能接受的,只好本身實現確認和重傳,說白了,就是本身實現TCP(固然是部分和有限的簡單實現)。
UDP是而向無鏈接的,用戶在實施UDP編程時,必須制定上層的協議,包括流控制,簡單的超時和重傳機制,若是不要求是實時數據,我想TCP可能會更適合你!
- huangcanbao 發表於Tuesday, September 22, 2009 7:33:22 PM IP:
- 今天接到了電話面試,還好個人解決方案和你這位朋友的同樣。1:給本身發的數據定義協議,序號 大小 數據。 2:傳輸過程都要進行雙方驗證,是否接受到正確的數據。根據傳輸的字節大小來管理的。
- 轉自 http://blog.csdn.net/yylklshmyt20090217/archive/2009/06/17/4275937.aspx
- 建議的辦法是,對於大的報文本身進行一個分包和組包操做.要減小丟包率(丟包重發,一樣是不小的消耗),把單包的大小定在1500字節之內,按24MBit/s的帶寬最大流通量2048個包每秒,這個壓力是至關小的.
- 丟包是很正常的,發包越大丟包的可能性就越高,與網卡速度沒有必然聯繫,須要本身設計應答和重發機制。至於多大的數據包最合適,要在實際運行的環境中測試才能知道。程序運行過程當中能夠本身統計並計算丟包率,而後動態調整數據包的大小來適應運行環境。 另外是內存池這些,最簡單的,你要是每次new char[1024]再去收,那收線程速度就當下來了.
-
記住,收線程不要作任何事.那怕只查個MAP,在上萬包每秒時,每秒的操做就上萬個MAP查詢,
-
另外丟包多是發送端,發出來已經丟了,你要考慮發送的的發送處理,發送處理寫得很差,其實發
-
的過程根本沒機會出網卡緩衝,就已經丟了有可能.
-
中間路由器環節(這個沒法控制,只能看看這個環節性能如何)