套接字緩沖區(qū)大小..." />
<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Netty如何解決TCP粘包半包難題?

          共 1099字,需瀏覽 3分鐘

           ·

          2020-12-14 09:38


          ? 點(diǎn)擊上方“JavaEdge”,關(guān)注公眾號(hào)

          設(shè)為“星標(biāo)”,好文章不錯(cuò)過(guò)!


          1 TCP為何會(huì)有粘包半包?




          1.1 粘包

          • 發(fā)送方每次寫(xiě)入數(shù)據(jù) < 套接字緩沖區(qū)大小

          • 接收方讀取套接字緩沖區(qū)數(shù)據(jù)不夠及時(shí)



          1.2 半包


          • 發(fā)送方寫(xiě)入數(shù)據(jù) > 套接字緩沖區(qū)大小

          • 發(fā)送的數(shù)據(jù)大于協(xié)議的MTU ( Maximum Transmission Unit,最大傳輸單元),必須拆包

          而且

          • 一個(gè)發(fā)送可能被多次接收,多個(gè)發(fā)送可能被一次接收

          • 一個(gè)發(fā)送可能占用多個(gè)傳輸包,多個(gè)發(fā)送可能公用一個(gè)傳輸包

          TCP 本質(zhì)上是流式協(xié)議,消息無(wú)邊界。

          而UDP就像快遞,雖然一次運(yùn)輸多個(gè),但每個(gè)包都有邊界,一個(gè)個(gè)簽收
          所以無(wú)此類(lèi)問(wèn)題。

          清楚了問(wèn)題產(chǎn)生的本質(zhì),那么就知道如何避免了,即確定消息的邊界。

          2 解決方案




          2.1 改為短連接


          一個(gè)請(qǐng)求一個(gè)短連接。建立連接到釋放連接之間的信息即為傳輸信息。
          簡(jiǎn)單,但效率低下,不推薦。



          2.2 封裝成幀


          2.2.1 固定長(zhǎng)度


          • 解碼:FixedLengthFrameDecoder

          • 滿足固定長(zhǎng)度即可。

          簡(jiǎn)單,但空間浪費(fèi),不推薦。

          2.2.2 分割符


          • 解碼:DelimiterBasedFrameDecoder,分隔符之間即為消息。

          空間不浪費(fèi),也比較簡(jiǎn)單,但內(nèi)容本身出現(xiàn)分隔符時(shí)需轉(zhuǎn)義,所以需掃描內(nèi)容。
          推薦度低。

          2.2.3 固定長(zhǎng)度字段存?zhèn)€內(nèi)容的長(zhǎng)度信息


          • 解碼:LengthFieldBasedFrameDecoder

          • 編碼:LengthFieldPrepender

          先解析固定長(zhǎng)度的字段獲取長(zhǎng)度,然后讀取后續(xù)內(nèi)容。這就沒(méi)有之前的缺點(diǎn)了

          精確定位用戶數(shù)據(jù),內(nèi)容也不用轉(zhuǎn)義。
          但長(zhǎng)度理論上有限制,需提前預(yù)知可能的最大長(zhǎng)度,從而定義長(zhǎng)度占用字節(jié)數(shù)。
          如果直接定義成最大長(zhǎng)度,但實(shí)際上每次傳輸?shù)挠诌h(yuǎn)沒(méi)達(dá)到最大值,不就浪費(fèi)空間啦,所以根據(jù)需要設(shè)置最大長(zhǎng)度。

          重點(diǎn)推薦使用。

          其他方式比如 json 可看{}是否已經(jīng)成對(duì)。但這種明顯要掃描全部?jī)?nèi)容才知道是否成對(duì),性能較低。




          往期推薦


          大廠如何解決數(shù)值精度/舍入/溢出問(wèn)題

          大廠數(shù)據(jù)庫(kù)事務(wù)實(shí)踐-事務(wù)生效就能保證正確回滾?

          線上問(wèn)題事跡(一)數(shù)據(jù)庫(kù)事務(wù)居然都沒(méi)生效?

          硬核干貨:HTTP超時(shí)、重復(fù)請(qǐng)求必見(jiàn)坑點(diǎn)及解決方案

          給大忙人們看的Java NIO教程之Channel





          目前交流群已有?800+人,旨在促進(jìn)技術(shù)交流,可關(guān)注公眾號(hào)添加筆者微信邀請(qǐng)進(jìn)群


          喜歡文章,點(diǎn)個(gè)“在看、點(diǎn)贊、分享”素質(zhì)三連支持一下~

          瀏覽 48
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  俺去电影院 | 青青草国产成人AV片免费 | 国产啊啊| 色老板精品无码免费播放 | 一本久道激情淫乱视频 |