• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            UDP丟包原因

            轉(zhuǎn)載自:http://www.cnblogs.com/mengyan/archive/2012/10/04/2711340.html

            一、主要丟包原因

            1、接收端處理時(shí)間過長導(dǎo)致丟包:調(diào)用recv方法接收端收到數(shù)據(jù)后,處理數(shù)據(jù)花了一些時(shí)間,處理完后再次調(diào)用recv方法,在這二次調(diào)用間隔里,發(fā)過來的包可能丟失。對(duì)于這種情況可以修改接收端,將包接收后存入一個(gè)緩沖區(qū),然后迅速返回繼續(xù)recv。

            2、發(fā)送的包巨大丟包:雖然send方法會(huì)幫你做大包切割成小包發(fā)送的事情,但包太大也不行。例如超過50K的一個(gè)udp包,不切割直接通過send方法發(fā)送也會(huì)導(dǎo)致這個(gè)包丟失。這種情況需要切割成小包再逐個(gè)send。

            3、發(fā)送的包較大,超過接受者緩存導(dǎo)致丟包:包超過mtu size數(shù)倍,幾個(gè)大的udp包可能會(huì)超過接收者的緩沖,導(dǎo)致丟包。這種情況可以設(shè)置socket接收緩沖。以前遇到過這種問題,我把接收緩沖設(shè)置成64K就解決了。
            int nRecvBuf=32*1024;//設(shè)置為32K
            setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

            具體設(shè)置代碼可以參考下面鏈接:
            http://blog.sina.com.cn/s/blog_a459dcf5010153mp.html

            4、發(fā)送的包頻率太快:雖然每個(gè)包的大小都小于mtu size 但是頻率太快,例如40多個(gè)mut size的包連續(xù)發(fā)送中間不sleep,也有可能導(dǎo)致丟包。這種情況也有時(shí)可以通過設(shè)置socket接收緩沖解決,但有時(shí)解決不了。所以在發(fā)送頻率過快的時(shí)候還是考慮sleep一下吧。

            5、局域網(wǎng)內(nèi)不丟包,公網(wǎng)上丟包。這個(gè)問題我也是通過切割小包并sleep發(fā)送解決的。如果流量太大,這個(gè)辦法也不靈了。總之udp丟包總是會(huì)有的,如果出現(xiàn)了用我的方法解決不了,還有這個(gè)幾個(gè)方法: 要么減小流量,要么換tcp協(xié)議傳輸,要么做丟包重傳的工作。

             

             

            二、具體問題分析

            1.發(fā)送頻率過高導(dǎo)致丟包

            很多人會(huì)不理解發(fā)送速度過快為什么會(huì)產(chǎn)生丟包,原因就是UDP的SendTo不會(huì)造成線程阻塞,也就是說,UDP的SentTo不會(huì)像TCP中的SendTo那樣,直到數(shù)據(jù)完全發(fā)送才會(huì)return回調(diào)用函數(shù),它不保證當(dāng)執(zhí)行下一條語句時(shí)數(shù)據(jù)是否被發(fā)送。(SendTo方法是異步的)這樣,如果要發(fā)送的數(shù)據(jù)過多或者過大,那么在緩沖區(qū)滿的那個(gè)瞬間要發(fā)送的報(bào)文就很有可能被丟失。至于對(duì)“過快”的解釋,作者這樣說:“A few packets a second are not an issue; hundreds or thousands may be an issue.”(一秒鐘幾個(gè)數(shù)據(jù)包不算什么,但是一秒鐘成百上千的數(shù)據(jù)包就不好辦了)。 要解決接收方丟包的問題很簡單,首先要保證程序執(zhí)行后馬上開始監(jiān)聽(如果數(shù)據(jù)包不確定什么時(shí)候發(fā)過來的話),其次,要在收到一個(gè)數(shù)據(jù)包后最短的時(shí)間內(nèi)重新回到監(jiān)聽狀態(tài),其間要盡量避免復(fù)雜的操作(比較好的解決辦法是使用多線程回調(diào)機(jī)制)。

            2.報(bào)文過大丟包

            至于報(bào)文過大的問題,可以通過控制報(bào)文大小來解決,使得每個(gè)報(bào)文的長度小于MTU。以太網(wǎng)的MTU通常是1500 bytes,其他一些諸如撥號(hào)連接的網(wǎng)絡(luò)MTU值為1280 bytes,如果使用speaking這樣很難得到MTU的網(wǎng)絡(luò),那么最好將報(bào)文長度控制在1280 bytes以下。

            3.發(fā)送方丟包

            發(fā)送方丟包:內(nèi)部緩沖區(qū)(internal buffers)已滿,并且發(fā)送速度過快(即發(fā)送兩個(gè)報(bào)文之間的間隔過短);  接收方丟包:Socket未開始監(jiān)聽;  雖然UDP的報(bào)文長度最大可以達(dá)到64 kb,但是當(dāng)報(bào)文過大時(shí),穩(wěn)定性會(huì)大大減弱。這是因?yàn)楫?dāng)報(bào)文過大時(shí)會(huì)被分割,使得每個(gè)分割塊(翻譯可能有誤差,原文是fragmentation)的長度小于MTU,然后分別發(fā)送,并在接收方重新組合(reassemble),但是如果其中一個(gè)報(bào)文丟失,那么其他已收到的報(bào)文都無法返回給程序,也就無法得到完整的數(shù)據(jù)了。 

            posted on 2013-01-15 15:20 楊粼波 閱讀(936) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            91精品久久久久久无码| 久久国产免费直播| 97久久精品人人做人人爽| 91久久九九无码成人网站| 国内精品久久久久久不卡影院| 久久精品国产亚洲5555| 久久久久久曰本AV免费免费| 99久久er这里只有精品18| 狠狠综合久久综合中文88| 狠狠色丁香久久婷婷综合_中| 久久ww精品w免费人成| 久久精品国产99久久丝袜| …久久精品99久久香蕉国产| 久久天天躁狠狠躁夜夜2020老熟妇 | 久久精品国产欧美日韩99热| 久久久无码一区二区三区| 欧美国产精品久久高清| 久久99热精品| 久久精品人人做人人妻人人玩| 久久久久18| 精品久久久久久国产| 人妻无码αv中文字幕久久| 亚洲AV伊人久久青青草原| 青青青青久久精品国产h| 久久久精品国产sm调教网站| 久久人人爽人人爽人人av东京热| 亚洲国产成人久久精品动漫| 成人久久综合网| 久久久久亚洲av无码专区导航| 最新久久免费视频| 久久人人爽人人澡人人高潮AV| 国产精品免费看久久久香蕉| 99麻豆久久久国产精品免费 | 2020最新久久久视精品爱| 久久精品九九亚洲精品| 亚洲AV日韩AV天堂久久| AV无码久久久久不卡蜜桃| 99精品国产99久久久久久97 | 久久人人爽人人爽人人片av麻烦 | 亚洲欧美精品一区久久中文字幕| 久久国产精品国语对白|