V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
error0
V2EX  ›  程序员

TCP 粘包? 到底有没有粘包?

  •  
  •   error0 · 2024-08-24 18:20:46 +08:00 · 8904 次点击
    这是一个创建于 374 天前的主题,其中的信息可能已经有所发展或是发生改变。

    听说这是贵站的月经贴! 关于 TCP 协议 ”粘包和拆包“ 的见解

    第 1 条附言  ·  2024-08-24 19:36:59 +08:00
    看见大家对 “TCP 粘包像是错误的设计” 有很大的看法,实际上我所想表达的是 “如果处理 TCP 粘包” 看起来是责怪 TCP 的问题。但是他们却对 “粘包” 这种说法确实觉得正确
    68 条回复    2024-08-27 10:25:32 +08:00
    error0
        1
    error0  
    OP
       2024-08-24 18:26:04 +08:00
    说好月经贴呢 人呢???
    R4rvZ6agNVWr56V0
        2
    R4rvZ6agNVWr56V0  
       2024-08-24 18:31:21 +08:00
    “TCP ”粘包和拆包“ 这个说法像是 TCP 的设计错误” —— 这只是 OP 自己的感觉吧。。。

    要正确处理 TCP 流数据,应用层需要:
    1.自己定义消息的边界,例如使用固定长度、长度字段、或特殊分隔符。
    2.在接收端根据定义的边界来解析完整的消息。
    3.不要假设一次接收的数据就是一个完整的消息。
    error0
        3
    error0  
    OP
       2024-08-24 18:34:37 +08:00
    @GeekGao 🤣你怎么跳过阅读到最后
    anjingdexiaocai
        4
    anjingdexiaocai  
       2024-08-24 18:35:28 +08:00 via Android   ❤️ 1
    个人理解所谓的粘包,拆包,都是应用层协议定义不明确,把锅甩给传输层。就好比装货和卸货两方自己不定义好规则,怪运输火车搞出问题。
    07aPzknB16ui9Cp3
        5
    07aPzknB16ui9Cp3  
       2024-08-24 18:35:47 +08:00   ❤️ 6
    引流的态度要不要这么屌的哦
    error0
        6
    error0  
    OP
       2024-08-24 18:35:48 +08:00
    @GeekGao 但是在很多技术论坛就是这样 ,很多书籍,以及面试题都再说 如何处理 tcp 粘包问题
    error0
        7
    error0  
    OP
       2024-08-24 18:36:17 +08:00
    R4rvZ6agNVWr56V0
        8
    R4rvZ6agNVWr56V0  
       2024-08-24 18:36:49 +08:00
    @error0 因为在我的印象里,没人说 TCP 协议有这种“设计错误” 啊,所以,我的认知里就不会存在你观察到的“问题“
    error0
        9
    error0  
    OP
       2024-08-24 18:37:50 +08:00
    @GeekGao 你可以到搜索引擎搜到 如何处理 tcp 粘包问题,这不就是再说是 tcp 的问题吗?
    error0
        10
    error0  
    OP
       2024-08-24 18:38:38 +08:00
    @GeekGao 就是有那种 为什么 tcp 不帮我处理好数据边界 要分开 有一种责怪的认为
    julyclyde
        11
    julyclyde  
       2024-08-24 18:40:06 +08:00
    @error0 你要是觉得能搜到就存在,那你的理解能力和逻辑都有问题
    julyclyde
        12
    julyclyde  
       2024-08-24 18:40:21 +08:00
    @error0 因为 TCP 是流,所以不负责处理边界
    error0
        13
    error0  
    OP
       2024-08-24 18:40:53 +08:00
    @julyclyde 请指出我的哪里理解不对。 感谢!
    R4rvZ6agNVWr56V0
        14
    R4rvZ6agNVWr56V0  
       2024-08-24 18:41:28 +08:00
    @error0
    1.这是应用层开发问题啊。无非就是词汇的释义问题罢了
    2.我没见到有帖子说这是 TCP 的协议缺陷啊。
    3.难不成取消这个词,非要改口为:“TCP 协议栈的应用层如何处理 TCP 流(数据不延续)问题” 类似的一长串话?
    julyclyde
        15
    julyclyde  
       2024-08-24 18:42:30 +08:00
    @error0 哪里不对?是逻辑不对
    tcp 是底层协议,你要分界的是高层协议
    底层对高层根本无感知,当然不负责去做分界了
    error0
        16
    error0  
    OP
       2024-08-24 18:45:31 +08:00
    @GeekGao 1 、确实是的,但是何必造出一个所谓的词汇?是没有词汇能解释这种现象? 2 、你可以 google 搜索 “如何处理 tcp 的粘包?” 这个问题会让别人以为这是 tcp 的缺陷,实际上是用户处理不当。3 、大部分有权威的网络书籍都在说 tcp 流不会按照用户所认为的长度传输。
    error0
        17
    error0  
    OP
       2024-08-24 18:46:09 +08:00
    @julyclyde 我所表达就是底层对高层无感知!
    R4rvZ6agNVWr56V0
        18
    R4rvZ6agNVWr56V0  
       2024-08-24 18:51:38 +08:00
    @error0

    我是觉得是你自己已有的知识领域的偏见(非贬义,因为每个人都有不同程度的偏见)导致了你的这次思考和质疑。
    关于词汇释义问题,未必说都是科学的,好比村妇喂鸡时大叫“咯咯咯咯”,有的人觉得应该改为“咕咕咕咕“才对。
    但是一旦形成了群体共识,那么就不好反驳了,毕竟你觉得对的,别人不会觉得对,何况本质上也没对错之分。
    oamu
        19
    oamu  
       2024-08-24 18:52:07 +08:00
    粘包👮来了!谁说粘包的通通带走!
    coderxy
        20
    coderxy  
       2024-08-24 18:52:54 +08:00
    说粘包的通通逮走
    maigebaoer
        21
    maigebaoer  
       2024-08-24 19:11:20 +08:00 via Android
    再说粘包,直接抓起来🔫打靶!
    Znemo
        22
    Znemo  
       2024-08-24 19:14:58 +08:00
    没见过有人觉得这是 tcp 的缺陷,不了解的人不敢质疑,了解的人知道咋回事。我反而觉得这个词会让人更近一步的了解 tcp 。
    seers
        23
    seers  
       2024-08-24 19:20:47 +08:00   ❤️ 1
    我倒觉得没啥,tcp 毕竟是字节流,包是上层定义的,在上层看来,底下的包不就是一个个粘在一起的吗哈哈哈
    james122333
        24
    james122333  
       2024-08-24 19:20:48 +08:00 via Android
    这是应用层处理资料逻辑 目前来看读行方式才是好的处理方法
    DefoliationM
        25
    DefoliationM  
       2024-08-24 19:23:27 +08:00 via Android
    人的问题,udp 太大到 ip 层也会分包,如果 ip 层的分片也是用户态自己写的话,那 ip/udp 粘包也会成为日常问题。
    DefoliationM
        26
    DefoliationM  
       2024-08-24 19:27:38 +08:00 via Android
    @DefoliationM 当然 ipv6 除外
    sagaxu
        27
    sagaxu  
       2024-08-24 19:30:33 +08:00
    这是 TCP 的缺陷,或者说不便(容易误用,使用麻烦)之处,所以后来的 SCTP 是基于帧的,只不过历史太重改不了了
    mx1700
        28
    mx1700  
       2024-08-24 19:58:09 +08:00 via Android   ❤️ 1
    文章写的很好,所谓的"粘包"现象实际上是对 "stream" 这个抽象设计的不理解
    littlewing
        29
    littlewing  
       2024-08-24 20:50:44 +08:00
    TCP 没有 package ,TCP 是 stream
    fovecifer
        30
    fovecifer  
       2024-08-24 21:14:21 +08:00
    你要是聊 TCP 的缺陷,那就太多了,要不然也不会有 QUIC 。

    但是谁再提粘包,那就别当程序员了
    iOCZS
        31
    iOCZS  
       2024-08-24 22:17:57 +08:00
    不同层次的问题
    wen20
        32
    wen20  
       2024-08-24 22:21:00 +08:00
    "粘包" 是个很早就有的词, 表示程序代码读取 tcp 流时发生了“非预期现象”,是一种错误使用。
    哪位觉的"粘包"这词不妥,给个合理新词描述这种现象?
    julyclyde
        33
    julyclyde  
       2024-08-24 22:22:31 +08:00
    @wen20 可以用“error”这个词
    julyclyde
        34
    julyclyde  
       2024-08-24 22:23:22 +08:00
    @wen20 mistake 这个词更合适吧。强调是主观错误而非客观错误
    Rorysky
        35
    Rorysky  
       2024-08-24 22:55:45 +08:00
    流式协议,黏豆包呀,什么你业务黏了,那和我传输层协议有什么关系?
    Bingchunmoli
        36
    Bingchunmoli  
       2024-08-24 22:59:42 +08:00 via Android
    @julyclyde error 不太合适,不是 TCP 的错误叫 tcp 错误不太合理
    anzu
        37
    anzu  
       2024-08-24 23:12:34 +08:00   ❤️ 6
    你提到的《 Netty 权威指南(第 2 版)》是国人写的,我还以为是翻译著作,给自己写的书冠以权威二字真是相当有勇气。计算机类书籍,不要看国内的写的,基本都是垃圾,就像这本一样,有意无意推广了「 TCP 粘包」这种错误的说法。
    xuxihai
        38
    xuxihai  
       2024-08-24 23:38:09 +08:00
    @error0 ` TCP 粘包? 到底有没有粘包?` 有啊!` “TCP 粘包像是错误的设计” ` 也没问题啊,这不是 TCP 的问题,“TCP 粘包“不是问题,"TCP 粘包"是一种现象!本质上是应用协议设计者没有考虑消息边界导致的一种现象。
    Kylin30
        39
    Kylin30  
       2024-08-24 23:59:29 +08:00
    他们吵起来是因为一边的”粘包“是动词,一边的”粘包“是名词。
    kenvix
        40
    kenvix  
       2024-08-25 00:12:01 +08:00 via Android
    当启用了 Nagle 时,会粘包。通常强烈建议考虑粘包的情况
    kenvix
        41
    kenvix  
       2024-08-25 00:14:17 +08:00 via Android
    也就是说,只要你没显式指定 TCP_NODELAY ,那就有可能粘
    cnbatch
        42
    cnbatch  
       2024-08-25 00:25:32 +08:00   ❤️ 2
    打个生活化的比喻:
    UDP 相当于带虚线的纸(例如厕所卷纸、针式打印机的打印纸),可以按照虚线一格一格拔断
    TCP 相当于购物小票打印纸,需要自己计算好切纸位置

    所谓“粘包”,相当于用惯虚线纸的人以为购物小票卷纸也是有虚线可以拔的,拿到手才发现没有虚线,总是断错位置。
    cnbatch
        43
    cnbatch  
       2024-08-25 00:27:17 +08:00
    所以“粘包”完全就是使用者自己用法错误,乱起“术语”
    conanxu
        44
    conanxu  
       2024-08-25 00:59:54 +08:00   ❤️ 1
    我只关心有没有粘豆包
    mingl0280
        45
    mingl0280  
       2024-08-25 08:25:34 +08:00
    TCP 哪来的包?你再说一遍粘什么?
    hekkowoerld
        46
    hekkowoerld  
       2024-08-25 10:24:19 +08:00
    nagle 只是优化机制,不是错误,国内技术圈自嗨的产物
    simenet
        47
    simenet  
       2024-08-25 11:17:47 +08:00
    再说粘 乱棍打死
    julyclyde
        48
    julyclyde  
       2024-08-25 11:54:47 +08:00
    @Bingchunmoli 是的。所以后来我又发了一句,觉得应该用 mistake 这个词
    est
        49
    est  
       2024-08-25 11:55:31 +08:00
    不沾只是偶然。
    iceheart
        50
    iceheart  
       2024-08-25 15:17:38 +08:00 via Android
    看起来是不懂 TCP 如何使用的程序员,在用 UDP 的方式处理数据的时候遇到了问题。他们又不承认自己错了,就发明了"粘包"这个词。
    offswitch
        51
    offswitch  
       2024-08-25 15:43:40 +08:00
    这玩意儿有什么好讨论的,一点技术含量都没有的东西。
    jinghong
        52
    jinghong  
       2024-08-25 15:47:12 +08:00
    一直不知道是读“zhan”还是读“nian”
    leaflxh
        53
    leaflxh  
       2024-08-25 16:32:30 +08:00   ❤️ 1
    对 TCP 包进行赋能,热了,就不粘了
    cwek
        54
    cwek  
       2024-08-25 16:38:02 +08:00   ❤️ 1
    首先记住 TCP 是一个流式负载的传输层协议,对上层应用层协议没有明确的报文长度机制,所以 100 字节输入进去,对面不保证一次读取就是 100 字节到齐(可能多次 1 字节交付,或者连后面再传入的 100 字节一起交付)。所以需要知道报文长度的应用层协议必须自己想办法制定应用层报文长度确认机制,不要靠 TCP 帮你解决这个问题,它不解决。
    cwek
        55
    cwek  
       2024-08-25 16:47:05 +08:00
    所以“粘包”这东西就是搞错了自己写基于有边界的应用层协议,通过 TCP 层传输时,会体现出 IP 层的传输边界,但实际上 TCP 层没有“传输边界”这玩意,就是一串在管子的粘性果冻串,透明到看不出边界,就算 IP 层将管子切成一段段,在连一边粘回一起,从管子出来时,还是一整条透明到看不到边界的粘性果冻串,所以应用层需要自己塞一些有颜色的果冻段来方便接受层知道,这一长串果冻是有边界的。
    cz5424
        56
    cz5424  
       2024-08-25 18:36:51 +08:00 via iPhone   ❤️ 2
    你是说水管黏水?
    totoro52
        57
    totoro52  
       2024-08-25 19:01:20 +08:00
    引战引流,这种人能不能处理掉啊, 真的浪费大家时间
    WuSiYu
        58
    WuSiYu  
       2024-08-25 19:19:48 +08:00   ❤️ 1
    一句话就能说明白:TCP 提供的接口形式是“流”,当用户错误的认为其形式是“包”时,其自然会“观察到”所谓粘包等现象,但这对于 TCP 其实是 as design 的

    我的观点:粘包确实是个东西,但要理解它是“建立在编程人员的错误理解之下的,一种自认为的现象”
    msg7086
        59
    msg7086  
       2024-08-26 06:47:20 +08:00
    TCP 没有包概念。TCP 本身会把流切成段,因为下层的 IP 协议是分包的。
    就像你统计人数坐大巴,本来好好按人头数来数就行了,有人偏要跑过来跟你说,我们今天来了 1.5 吨人,大巴一个座位坐 100 公斤人,需要 15 个座位。你不把他当傻子么。
    zhangsanfeng2012
        60
    zhangsanfeng2012  
       2024-08-26 07:43:32 +08:00 via Android
    其实是 ip 粘包🐶
    marcong95
        61
    marcong95  
       2024-08-26 09:40:07 +08:00
    用粘包两个字可以特定明确地描述类似于「应用层没有正确处理使用 TCP 协议传输数据时的消息边界问题」这种长篇大论的正确描述,我觉得倒也无妨。粘包警察要是能提出一个简短的术语大家应该也并不介意使用。非要追求绝对正确那要不参考大陆提到部分涉台用语时加个引号?
    xxxccc
        62
    xxxccc  
       2024-08-26 09:49:21 +08:00
    说了多少遍了,tcp 传输的是流,不是包
    error0
        63
    error0  
    OP
       2024-08-26 09:57:34 +08:00
    @marcong95 如果能明确描述那应该是没有争议才对
    ugpu
        64
    ugpu  
       2024-08-26 10:05:29 +08:00
    没办法 历史包袱吧.
    毕竟把这么多抽象的数据发出去 肯定不能在关心数据大小 / 内容 / 格式.都是流 二进制.
    反过来接收也一样
    coderzhangsan
        65
    coderzhangsan  
       2024-08-26 11:49:36 +08:00
    从计算机很多术语翻译来看,计算机也有很多一知半解的民科,没有系统性理解 TCP/IP ,TCP/IP 是流协议,应用层如何处理流,那是应用协议的问题,就如#56 所说,水管怎么处理粘水一样幽默🤣
    kxg3030
        66
    kxg3030  
       2024-08-26 11:50:34 +08:00
    粘人可以 粘包不行
    CloudSen
        67
    CloudSen  
       2024-08-26 13:09:52 +08:00 via iPhone
    @leaflxh 注入正能量
    tyc
        68
    tyc  
       2024-08-27 10:25:32 +08:00
    @xxxccc 理论上是流,实际上还是包
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3045 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:43 · PVG 20:43 · LAX 05:43 · JFK 08:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.