• <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 .

            處理TCP網(wǎng)絡(luò)傳輸“粘包”疑難

            處理TCP網(wǎng)絡(luò)傳輸粘包疑難

             

            在應(yīng)用開發(fā)過(guò)程中,筆者發(fā)現(xiàn)基于TCP網(wǎng)絡(luò)傳輸?shù)膽?yīng)用程序有時(shí)會(huì)出現(xiàn)粘包現(xiàn)象(即發(fā)送方發(fā)送的若干包數(shù)據(jù)到接收方接收時(shí)粘成一包)。針對(duì)這種情況,我們進(jìn)行了專題研究與實(shí)驗(yàn)。本文重點(diǎn)分析了TCP網(wǎng)絡(luò)粘包問(wèn)題,并結(jié)合實(shí)驗(yàn)結(jié)果提出了解決該問(wèn)題的對(duì)策和方法,供有關(guān)工程技術(shù)人員參考。

             

            一、TCP協(xié)議簡(jiǎn)介

              TCP是一個(gè)面向連接的傳輸層協(xié)議,雖然TCP不屬于iso制定的協(xié)議集,但由于其在商業(yè)界和工業(yè)界的成功應(yīng)用,它已成為事實(shí)上的網(wǎng)絡(luò)標(biāo)準(zhǔn),廣泛應(yīng)用于各種網(wǎng)絡(luò)主機(jī)間的通信。

              作為一個(gè)面向連接的傳輸層協(xié)議,TCP的目標(biāo)是為用戶提供可靠的端到端連接,保證信息有序無(wú)誤的傳輸。它除了提供基本的數(shù)據(jù)傳輸功能外,還為保證可靠性采用了數(shù)據(jù)編號(hào)、校驗(yàn)和計(jì)算、數(shù)據(jù)確認(rèn)等一系列措施。它對(duì)傳送的每個(gè)數(shù)據(jù)字節(jié)都進(jìn)行編號(hào),并請(qǐng)求接收方回傳確認(rèn)信息(ack)。發(fā)送方如果在規(guī)定的時(shí)間內(nèi)沒有收到數(shù)據(jù)確認(rèn),就重傳該數(shù)據(jù)。數(shù)據(jù)編號(hào)使接收方能夠處理數(shù)據(jù)的失序和重復(fù)問(wèn)題。數(shù)據(jù)誤碼問(wèn)題通過(guò)在每個(gè)傳輸?shù)臄?shù)據(jù)段中增加校驗(yàn)和予以解決,接收方在接收到數(shù)據(jù)后檢查校驗(yàn)和,若校驗(yàn)和有誤,則丟棄該有誤碼的數(shù)據(jù)段,并要求發(fā)送方重傳。流量控制也是保證可靠性的一個(gè)重要措施,若無(wú)流控,可能會(huì)因接收緩沖區(qū)溢出而丟失大量數(shù)據(jù),導(dǎo)致許多重傳,造成網(wǎng)絡(luò)擁塞惡性循環(huán)。TCP采用可變窗口進(jìn)行流量控制,由接收方控制發(fā)送方發(fā)送的數(shù)據(jù)量。

              TCP為用戶提供了高可靠性的網(wǎng)絡(luò)傳輸服務(wù),但可靠性保障措施也影響了傳輸效率。因此,在實(shí)際工程應(yīng)用中,只有關(guān)鍵數(shù)據(jù)的傳輸才采用TCP,而普通數(shù)據(jù)的傳輸一般采用高效率的udp。

            二、粘包問(wèn)題分析與對(duì)策

              TCP粘包是指發(fā)送方發(fā)送的若干包數(shù)據(jù)到接收方接收時(shí)粘成一包,從接收緩沖區(qū)看,后一包數(shù)據(jù)的頭緊接著前一包數(shù)據(jù)的尾。

              出現(xiàn)粘包現(xiàn)象的原因是多方面的,它既可能由發(fā)送方造成,也可能由接收方造成。發(fā)送方引起的粘包是由TCP協(xié)議本身造成的,TCP為提高傳輸效率,發(fā)送方往往要收集到足夠多的數(shù)據(jù)后才發(fā)送一包數(shù)據(jù)。若連續(xù)幾次發(fā)送的數(shù)據(jù)都很少,通常TCP會(huì)根據(jù)優(yōu)化算法把這些數(shù)據(jù)合成一包后一次發(fā)送出去,這樣接收方就收到了粘包數(shù)據(jù)。接收方引起的粘包是由于接收方用戶進(jìn)程不及時(shí)接收數(shù)據(jù),從而導(dǎo)致粘包現(xiàn)象。這是因?yàn)榻邮辗较劝咽盏降臄?shù)據(jù)放在系統(tǒng)接收緩沖區(qū),用戶進(jìn)程從該緩沖區(qū)取數(shù)據(jù),若下一包數(shù)據(jù)到達(dá)時(shí)前一包數(shù)據(jù)尚未被用戶進(jìn)程取走,則下一包數(shù)據(jù)放到系統(tǒng)接收緩沖區(qū)時(shí)就接到前一包數(shù)據(jù)之后,而用戶進(jìn)程根據(jù)預(yù)先設(shè)定的緩沖區(qū)大小從系統(tǒng)接收緩沖區(qū)取數(shù)據(jù),這樣就一次取到了多包數(shù)據(jù)(圖1所示)。


            圖1


            圖2


            圖3

              粘包情況有兩種,一種是粘在一起的包都是完整的數(shù)據(jù)包(圖1、圖2所示),另一種情況是粘在一起的包有不完整的包(圖3所示),此處假設(shè)用戶接收緩沖區(qū)長(zhǎng)度為m個(gè)字節(jié)。

              不是所有的粘包現(xiàn)象都需要處理,若傳輸?shù)臄?shù)據(jù)為不帶結(jié)構(gòu)的連續(xù)流數(shù)據(jù)(如文件傳輸),則不必把粘連的包分開(簡(jiǎn)稱分包)。但在實(shí)際工程應(yīng)用中,傳輸?shù)臄?shù)據(jù)一般為帶結(jié)構(gòu)的數(shù)據(jù),這時(shí)就需要做分包處理。

              在處理定長(zhǎng)結(jié)構(gòu)數(shù)據(jù)的粘包問(wèn)題時(shí),分包算法比較簡(jiǎn)單;在處理不定長(zhǎng)結(jié)構(gòu)數(shù)據(jù)的粘包問(wèn)題時(shí),分包算法就比較復(fù)雜。特別是如圖3所示的粘包情況,由于一包數(shù)據(jù)內(nèi)容被分在了兩個(gè)連續(xù)的接收包中,處理起來(lái)難度較大。實(shí)際工程應(yīng)用中應(yīng)盡量避免出現(xiàn)粘包現(xiàn)象。

              為了避免粘包現(xiàn)象,可采取以下幾種措施。一是對(duì)于發(fā)送方引起的粘包現(xiàn)象,用戶可通過(guò)編程設(shè)置來(lái)避免,TCP提供了強(qiáng)制數(shù)據(jù)立即傳送的操作指令push,TCP軟件收到該操作指令后,就立即將本段數(shù)據(jù)發(fā)送出去,而不必等待發(fā)送緩沖區(qū)滿;二是對(duì)于接收方引起的粘包,則可通過(guò)優(yōu)化程序設(shè)計(jì)、精簡(jiǎn)接收進(jìn)程工作量、提高接收進(jìn)程優(yōu)先級(jí)等措施,使其及時(shí)接收數(shù)據(jù),從而盡量避免出現(xiàn)粘包現(xiàn)象;三是由接收方控制,將一包數(shù)據(jù)按結(jié)構(gòu)字段,人為控制分多次接收,然后合并,通過(guò)這種手段來(lái)避免粘包。

              以上提到的三種措施,都有其不足之處。第一種編程設(shè)置方法雖然可以避免發(fā)送方引起的粘包,但它關(guān)閉了優(yōu)化算法,降低了網(wǎng)絡(luò)發(fā)送效率,影響應(yīng)用程序的性能,一般不建議使用。第二種方法只能減少出現(xiàn)粘包的可能性,但并不能完全避免粘包,當(dāng)發(fā)送頻率較高時(shí),或由于網(wǎng)絡(luò)突發(fā)可能使某個(gè)時(shí)間段數(shù)據(jù)包到達(dá)接收方較快,接收方還是有可能來(lái)不及接收,從而導(dǎo)致粘包。第三種方法雖然避免了粘包,但應(yīng)用程序的效率較低,對(duì)實(shí)時(shí)應(yīng)用的場(chǎng)合不適合。

              一種比較周全的對(duì)策是:接收方創(chuàng)建一預(yù)處理線程,對(duì)接收到的數(shù)據(jù)包進(jìn)行預(yù)處理,將粘連的包分開。對(duì)這種方法我們進(jìn)行了實(shí)驗(yàn),證明是高效可行的。

            、編程與實(shí)現(xiàn)

              1.實(shí)現(xiàn)框架

              實(shí)驗(yàn)網(wǎng)絡(luò)通信程序采用TCP/IP協(xié)議的socket api編程實(shí)現(xiàn)。socket是面向客戶機(jī)/服務(wù)器模型的。TCP實(shí)現(xiàn)框架如圖4所示。

            圖4

              2.實(shí)驗(yàn)硬件環(huán)境:

              服務(wù)器:pentium 350 微機(jī)

              客戶機(jī):pentium 166微機(jī)

              網(wǎng)絡(luò)平臺(tái):由10兆共享式hub連接而成的局域網(wǎng)

              3.實(shí)驗(yàn)軟件環(huán)境:

              操作系統(tǒng):windows 98

              編程語(yǔ)言:visual c++ 5.0

              4.主要線程

              編程采用多線程方式,服務(wù)器端共有兩個(gè)線程:發(fā)送數(shù)據(jù)線程、發(fā)送統(tǒng)計(jì)顯示線程。客戶端共有三個(gè)線程:接收數(shù)據(jù)線程、接收預(yù)處理粘包線程、接收統(tǒng)計(jì)顯示線程。其中,發(fā)送和接收線程優(yōu)先級(jí)設(shè)為thread_priority_time_critical(最高優(yōu)先級(jí)),預(yù)處理線程優(yōu)先級(jí)為thread_priority_above_normal(高于普通優(yōu)先級(jí)),顯示線程優(yōu)先級(jí)為thread_priority_normal(普通優(yōu)先級(jí))。

              實(shí)驗(yàn)發(fā)送數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)如圖5所示:

            圖5

              5.分包算法

              針對(duì)三種不同的粘包現(xiàn)象,分包算法分別采取了相應(yīng)的解決辦法。其基本思路是首先將待處理的接收數(shù)據(jù)流(長(zhǎng)度設(shè)為m)強(qiáng)行轉(zhuǎn)換成預(yù)定的結(jié)構(gòu)數(shù)據(jù)形式,并從中取出結(jié)構(gòu)數(shù)據(jù)長(zhǎng)度字段,即圖5中的n,而后根據(jù)n計(jì)算得到第一包數(shù)據(jù)長(zhǎng)度。

              1)若n<m,則表明數(shù)據(jù)流包含多包數(shù)據(jù),從其頭部截取n個(gè)字節(jié)存入臨時(shí)緩沖區(qū),剩余部分?jǐn)?shù)據(jù)依此繼續(xù)循環(huán)處理,直至結(jié)束。

              2)若n=m,則表明數(shù)據(jù)流內(nèi)容恰好是一完整結(jié)構(gòu)數(shù)據(jù),直接將其存入臨時(shí)緩沖區(qū)即可。

              3)若n>m,則表明數(shù)據(jù)流內(nèi)容尚不夠構(gòu)成一完整結(jié)構(gòu)數(shù)據(jù),需留待與下一包數(shù)據(jù)合并后再行處理。

              對(duì)分包算法具體內(nèi)容及軟件實(shí)現(xiàn)有興趣者,可與作者聯(lián)系。

            四、實(shí)驗(yàn)結(jié)果分析

              實(shí)驗(yàn)結(jié)果如下:

              1.在上述實(shí)驗(yàn)環(huán)境下,當(dāng)發(fā)送方連續(xù)發(fā)送的若干包數(shù)據(jù)長(zhǎng)度之和小于1500b時(shí),常會(huì)出現(xiàn)粘包現(xiàn)象,接收方經(jīng)預(yù)處理線程處理后能正確解開粘在一起的包。若程序中設(shè)置了“發(fā)送不延遲”:(setsockopt (socket_name,ipproto_tcp,tcp_nodelay,(char *) &on,sizeof on) ,其中on=1),則不存在粘包現(xiàn)象。

              2.當(dāng)發(fā)送數(shù)據(jù)為每包1kb~2kb的不定長(zhǎng)數(shù)據(jù)時(shí),若發(fā)送間隔時(shí)間小于10ms,偶爾會(huì)出現(xiàn)粘包,接收方經(jīng)預(yù)處理線程處理后能正確解開粘在一起的包。

              3.為測(cè)定處理粘包的時(shí)間,發(fā)送方依次循環(huán)發(fā)送長(zhǎng)度為1.5kb、1.9kb、1.2kb、1.6kb、1.0kb數(shù)據(jù),共計(jì)1000包。為制造粘包現(xiàn)象,接收線程每次接收前都等待10ms,接收緩沖區(qū)設(shè)為5000b,結(jié)果接收方收到526包數(shù)據(jù),其中長(zhǎng)度為5000b的有175包。經(jīng)預(yù)處理線程處理可得到1000包正確數(shù)據(jù),粘包處理總時(shí)間小于1ms。

              實(shí)驗(yàn)結(jié)果表明,TCP粘包現(xiàn)象確實(shí)存在,但可通過(guò)接收方的預(yù)處理予以解決,而且處理時(shí)間非常短(實(shí)驗(yàn)中1000包數(shù)據(jù)總共處理時(shí)間不到1ms),幾乎不影響應(yīng)用程序的正常工作。

             

            本文轉(zhuǎn)載自網(wǎng)絡(luò)
            來(lái)源:
            http://www.qqgb.com/Program/VC/VCnet/Program_104360.html

             

            posted on 2008-10-18 01:20 楊粼波 閱讀(1113) 評(píng)論(1)  編輯 收藏 引用

            評(píng)論

            # re: 處理TCP網(wǎng)絡(luò)傳輸“粘包”疑難 2008-10-18 21:39 LOGOS

            win98,VC5.0,可見這是多老的文章
            根本沒有粘包這種東西,TCP本身是流協(xié)議,包這種概念,不過(guò)是人加上的
            至于收包和分包,中規(guī)中矩的解決方案是:
            1.TCP棧收到包后,立即拷貝到用戶空間的一段循環(huán)緩沖區(qū)上
            2.回調(diào)OnRead
            3.在OnRead中,進(jìn)行分包。包結(jié)構(gòu)像文章的圖5那樣也行,不過(guò)類型是多余的,分包的話有包的長(zhǎng)度就夠了。長(zhǎng)度不屬于包邏輯的一部分,而類型則是
            4.根據(jù)包長(zhǎng)度從循環(huán)緩沖區(qū)中讀取完整的包進(jìn)行處理,重復(fù)這個(gè)過(guò)程,直到?jīng)]法讀取出完整的包為止
            5.清除循環(huán)緩沖區(qū)上已經(jīng)被處理的包

            總而言之,TCP粘包什么的,根本就不存在。文章居然還搞得多線程什么的。。。
              回復(fù)  更多評(píng)論   


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


            色播久久人人爽人人爽人人片aV| 国产AV影片久久久久久| 亚洲AV无一区二区三区久久| 久久久国产打桩机| 久久人妻少妇嫩草AV无码专区| 久久91精品国产91久久麻豆| 久久久久综合中文字幕| 欧洲人妻丰满av无码久久不卡| 国产巨作麻豆欧美亚洲综合久久| 亚洲精品无码久久毛片| 国产精品视频久久| 亚洲性久久久影院| 国产一区二区精品久久| 亚洲精品乱码久久久久久不卡| 伊人久久大香线蕉影院95| 伊人久久无码中文字幕| 99久久综合国产精品二区| 新狼窝色AV性久久久久久| 久久久久一级精品亚洲国产成人综合AV区| 精品国产日韩久久亚洲| 热99re久久国超精品首页| 香蕉久久夜色精品升级完成| 2020国产成人久久精品| 久久精品一区二区三区中文字幕| 久久婷婷五月综合色高清| 久久人妻少妇嫩草AV蜜桃| 伊人久久大香线蕉综合5g| 久久久久国产| 香蕉久久夜色精品国产小说| 伊人久久精品无码av一区| 欧美午夜A∨大片久久 | 久久人人爽人人爽人人AV| 亚洲午夜精品久久久久久app| 99久久精品免费国产大片| 国产麻豆精品久久一二三| 久久久久久无码Av成人影院| 久久久无码精品亚洲日韩按摩| 久久精品aⅴ无码中文字字幕不卡| 色综合久久久久综合体桃花网| 国色天香久久久久久久小说| 精品国产乱码久久久久软件|