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

我工作五年的时候也不知道 “TCP 粘包”

  •  
  •   sagaxu · 2018-12-20 10:35:02 +08:00 via Android · 21156 次点击
    这是一个创建于 2195 天前的主题,其中的信息可能已经有所发展或是发生改变。
    也不知道 cake(cache)是什么,比 catch 还难猜
    还有 marven(maven),第一次听时也没反应过来
    无限级,无限分类,直接说树和递归不好吗?
    C 井倒是马上就能联想到是 csharp
    100 条回复    2018-12-23 15:15:46 +08:00
    ackfin01
        1
    ackfin01  
       2018-12-20 10:47:49 +08:00   ❤️ 1
    233333333 上大学的时候看到 C++,惊呼 C 草
    codermagefox
        2
    codermagefox  
       2018-12-20 10:48:58 +08:00 via iPhone
    我一直就念 C 井
    一开始是真不知道,后来是装不知道,哈哈
    Chingim
        3
    Chingim  
       2018-12-20 10:49:51 +08:00 via Android
    所以 TCP 粘包到底是啥
    Chingim
        4
    Chingim  
       2018-12-20 10:50:29 +08:00 via Android   ❤️ 5
    还有你知道什么叫阿贾克斯吗哈哈哈
    xkeyideal
        5
    xkeyideal  
       2018-12-20 10:52:48 +08:00   ❤️ 2
    汤姆凯特和瑞迪斯你了解么
    HankAviator
        6
    HankAviator  
       2018-12-20 10:53:07 +08:00   ❤️ 1
    @codermagefox 以前故意恶搞程序员朋友,说 C pound sign,他瞬间就疯了哈哈
    zsdroid
        7
    zsdroid  
       2018-12-20 10:54:39 +08:00
    芒果数据库了解一下
    reus
        8
    reus  
       2018-12-20 10:56:30 +08:00   ❤️ 2
    字节序就是 byte order
    BOM 就是 Byte Order Mark,就是字节顺序标记
    你说字节序不如字节顺序容易懂也就算了,说到字节序都毫无概念的,只能说,基础太差
    这不是术语有问题,是知识有问题
    就是这样
    TheWalkingDead
        9
    TheWalkingDead  
       2018-12-20 10:57:52 +08:00   ❤️ 2
    @reus

    +1 杠精都是 250,不愿意正面面对自己基础知识薄弱的劣势。
    ghiei9101
        10
    ghiei9101  
       2018-12-20 10:59:21 +08:00
    够浪你又了不了解?
    linxiaoziruo
        11
    linxiaoziruo  
       2018-12-20 10:59:40 +08:00   ❤️ 2
    @Chingim 简而言之,就是 TCP 不管你发出的数据包的业务含义,它只考虑一次性发多少字节比较合适,这就导致了有可能两个不相关的数据包被合并发送,这就叫粘包。解决办法就是设置包的业务边界,直到边界出现再取出完整的包。
    meik2333
        12
    meik2333  
       2018-12-20 11:00:43 +08:00   ❤️ 1
    TCP 粘包是因为 TCP 是一种流传输协议,你无法保证发送多个包会怎样被接收,很可能你发送了两个包,一次接收到了一个半,此时就发生了 TCP 粘包。

    不过我还真不知道这玩意儿的英文名是啥[\捂脸]。。。。。。
    TheWalkingDead
        13
    TheWalkingDead  
       2018-12-20 11:01:52 +08:00   ❤️ 1
    tcp 粘包这种概念应该在任何一本讲网络编程的书里面都会提到,理解的深入不深入那是另外一回事,至少要明白基本是个什么情况吧。
    好,你说你没学过网络编程,那你大学干啥去了,哦,你说你大学学的做网站?哦,那你和外面培训班出来的有什么区别。
    reus
        14
    reus  
       2018-12-20 11:02:17 +08:00   ❤️ 3
    “ TCP 粘包”是不懂 TCP 的人发明的垃圾术语,和“字节序”是一样的吗请问?

    字节序甚至还不等于大小端序,还有混合序的,“字节序”就是统称

    你听说过猪牛羊,说到哺乳动物你就不知道,难道不是知识水平不够?
    petelin
        15
    petelin  
       2018-12-20 11:04:36 +08:00   ❤️ 12
    @TheWalkingDead
    @meik2333
    @linxiaoziruo
    找到英文,是因为根本没有这个东西, 你从任何流里读数据都会遇到这个"问题". 这是一个很简单的事情, 生生被国内半吊子傻逼搞成一个名词然后抨击 TCP 设计有问题. 看见这个词就生气.
    bankroft
        16
    bankroft  
       2018-12-20 11:04:42 +08:00 via Android   ❤️ 2
    每次看到这种中文术语我总能联想到"鲁棒性"
    petelin
        17
    petelin  
       2018-12-20 11:05:16 +08:00
    @reus 是这样的. 大佬是不是知乎也有账号, 经常回复 Go 问题的? 好像都关注你了..
    mind3x
        18
    mind3x  
       2018-12-20 11:06:24 +08:00   ❤️ 27
    我倒想知道是哪个平行世界的“任何一本讲网络编程的书”都会提到“ tcp 粘包这种概念”。笑死老子了。
    petelin
        19
    petelin  
       2018-12-20 11:07:16 +08:00
    @bankroft 我的天啊啊...............鲁棒性是 Robustness 的翻译, 你可以吐槽这个翻译没有水准, 但是跟什么楼主说的有一点关系吗?

    你这种就像是吐槽, 中国在英文术语里叫 "瓷器"
    maokabc
        20
    maokabc  
       2018-12-20 11:08:30 +08:00 via Android
    严格来说这不叫粘包。本来就是流,怎么分包得自己定义吧,一般都是自述长度或者转义加分隔符
    bankroft
        21
    bankroft  
       2018-12-20 11:10:51 +08:00 via Android
    @petelin 我没说有关系啊,个人联想而已。。。没办法,当时考试考这个很难记,所以对这个有很大的 emmm...怨念
    neoblackcap
        22
    neoblackcap  
       2018-12-20 11:13:31 +08:00   ❤️ 2
    楼上加一,TCP 粘包没有一本好的网络编程书会说。这个就是解析包的内容没做好。一个流的协议,怎么会出现包的概念呢?包也是应用层人为加进去的,明显就是写程序的人没做好
    kakudesu
        23
    kakudesu  
       2018-12-20 11:16:25 +08:00
    所以说,c 艹,c 井到底怎么念?
    trait
        24
    trait  
       2018-12-20 11:20:33 +08:00   ❤️ 1
    什么鬼粘包,怕不是野鸡培训班里创造出来的特色词汇。看了这么多书,从来没遇到过
    tingfang
        25
    tingfang  
       2018-12-20 11:25:30 +08:00
    粘包,有没有大佬说一下第一个字读什么? nián ? zhān ?
    zpf124
        26
    zpf124  
       2018-12-20 11:25:56 +08:00
    @kakudesu
    字正腔圆的念 西、普拉斯、普拉斯 , 西、沙埔 (认真脸)。
    Earl
        27
    Earl  
       2018-12-20 11:27:26 +08:00
    @bankroft 看你天天吐槽“鲁棒”,是不是也应该去吐槽一下“写真”、“芭蕾”、“卢布”等音译词?“鲁棒”本来就是被广泛应用的音译词,有啥可吐槽的?
    boris1993
        28
    boris1993  
       2018-12-20 11:27:52 +08:00 via Android
    @zpf124 #26 不应该是 sei 夏普 吗 /滑稽
    BOYPT
        29
    BOYPT  
       2018-12-20 11:28:33 +08:00   ❤️ 3
    “粘包”这个概念如果真进去书里面那才是灾难。
    bankroft
        30
    bankroft  
       2018-12-20 11:29:47 +08:00 via Android
    @Earl 总共发了两次,天天[黑人❓]
    mytry
        31
    mytry  
       2018-12-20 11:29:58 +08:00
    我工作五年的时候也不知道 “安全套接字” 🐶
    momocraft
        32
    momocraft  
       2018-12-20 11:32:01 +08:00   ❤️ 2
    粘包这个说法仿佛在假定从 socket 读到的是包,而且这些“包”还应该按消息分隔好。
    实际上 TCP API 的语义上就没有包的概念,更不要说粘。

    名字会反映人的理解,还会影响人的思考,不是小事。
    maemual
        33
    maemual  
       2018-12-20 11:36:44 +08:00
    @Chingim #4 知道啊,荷甲球队。 :doge:
    laoyur
        34
    laoyur  
       2018-12-20 11:36:54 +08:00
    @zpf124 沙埔? 233333
    yicong135
        35
    yicong135  
       2018-12-20 11:37:32 +08:00
    遇到过奇葩说法:程序里超线程概念就是子线程创建的线程;当时一脸懵逼
    laoyur
        36
    laoyur  
       2018-12-20 11:37:35 +08:00
    @boris1993 sei ? 233333
    SeaRecluse
        37
    SeaRecluse  
       2018-12-20 11:39:59 +08:00
    @Earl 然而“鲁棒”并不是音译词,这个词的由来是一桩公案了。在许久之前,业界就已经不建议使用“鲁棒”一词。只是教材具有落后性,很多没有改。
    liuxey
        38
    liuxey  
       2018-12-20 11:41:52 +08:00
    现在很多人都没写过 TCP 程序,更别说封装个协议,上次有个人和我对接 TCP 接口煞有介事得问我要是粘包怎么处理,我想想还是不解释了。
    janhu9527
        39
    janhu9527  
       2018-12-20 11:45:02 +08:00
    如果别人问题红黑树怎么实现,确实是难为人,别人问你红黑树是啥,你说没听过,这不是基础差是什么?毕竟都是做 CRUD 的码农
    ChoateYao
        40
    ChoateYao  
       2018-12-20 11:45:09 +08:00
    沟通,不就是让对方了解你的意思吗?

    就像不同的群体聊不同的梗,你不解释对方根本不知道你在说什么。

    说回来计算机术语,很多计算机术语从英文翻译回中文,很多时候并不能准确指出原有的意思。

    socket 翻译成 套接字,第一次看到能把这两个词联想到一起?
    Earl
        41
    Earl  
       2018-12-20 11:48:09 +08:00
    @SeaRecluse 你所说的公案我不太了解,我看到的大多都是说是音译词。可能有些业界不用“鲁棒”了,至少在控制领域,一直用的“鲁棒”,也一直说“鲁棒控制”,没人会说“健壮控制”的。因为有些领域不用,就吐槽,没必要吧。
    Vegetable
        42
    Vegetable  
       2018-12-20 11:48:25 +08:00 via Android
    @Earl 还是有点差别的吧,音译一般是比较具象的,这个鲁棒显得抽象了,抽象的特征翻译一般是通过中文重新描述一下来翻译的吧。这更像是日本或者台湾的翻译风格
    Earl
        43
    Earl  
       2018-12-20 11:53:12 +08:00   ❤️ 1
    @Vegetable 对,所以“鲁棒”不算好的翻译,但被广泛应用的词,没有必要 diss 啊。比如“芭蕾”,光看字也不知道是舞蹈,只是变成习惯了,所以大家一说芭蕾就知道是舞蹈。
    cs371332219
        44
    cs371332219  
       2018-12-20 12:03:51 +08:00
    @kakudesu C 艹艹
    waruqi
        45
    waruqi  
       2018-12-20 12:07:13 +08:00 via Android
    这种伪概念 误人子弟
    rayhy
        46
    rayhy  
       2018-12-20 12:08:18 +08:00 via Android
    @kakudesu plus plus & sharp?
    xomix
        47
    xomix  
       2018-12-20 12:36:22 +08:00
    @Vegetable #42 不能这样吐槽别人翻译,你看看缓存(cache)别人翻译叫 快取 是不是比缓存高大上多了还能兼顾发音问题
    smilekung
        48
    smilekung  
       2018-12-20 13:14:08 +08:00
    @Earl 这个确实 控制领域各种鲁棒 上学得时候看得这个词疑惑了好久
    misaka19000
        49
    misaka19000  
       2018-12-20 13:19:24 +08:00
    你不知道是正常的,因为 TCP 是一个流,不存在 包 的概念,这个所谓的 粘包 估计是什么山寨作者自己杜撰出来的
    zkeeper
        50
    zkeeper  
       2018-12-20 13:22:10 +08:00
    我工作时间比你还多, 也不知道什么是"粘包", 这是不知道谁自己翻译的名词吧?
    zackkson1991
        51
    zackkson1991  
       2018-12-20 13:24:58 +08:00
    闻道有先后,术业有专攻。这些问题就结束好了~
    tabris17
        52
    tabris17  
       2018-12-20 13:26:53 +08:00
    不是 TCP 粘豆包吗?
    tabris17
        53
    tabris17  
       2018-12-20 13:28:14 +08:00
    @meik2333 哈哈哈,你都被谁忽悠瘸了
    nicevar
        54
    nicevar  
       2018-12-20 13:35:51 +08:00
    说实话我工作十来年了,也不知道字节序和粘包这些叫法是什么时候出来的,感觉就是今年才见到
    Perry
        55
    Perry  
       2018-12-20 13:38:51 +08:00
    当时发现 Binary Tree 的中文叫二叉树的时候也是很惊讶的
    EastLord
        56
    EastLord  
       2018-12-20 13:41:17 +08:00   ❤️ 1
    记特哈勃
    liuminghao233
        57
    liuminghao233  
       2018-12-20 13:49:48 +08:00 via iPhone   ❤️ 1
    有时候
    tcp 接收数据时 需要处理数据边界的问题
    粘包说的实就是这个问题
    解决方法就是加个 header 表示下长度就 ok 了

    当然网络编程的书不应该有粘包这种东西
    那是 tcp 上层具体业务逻辑的问题

    另外这个术语定义也很尴尬
    这种问题只会出现在 tcp 上
    只说粘包又好像少了什么
    说 “ tcp 粘包”又是不准确的
    因为不是所有 tcp 程序都需要处理”粘包”的问题

    要不你们来为这个问题起个名字吧
    HanMeiM
        58
    HanMeiM  
       2018-12-20 15:04:20 +08:00
    公司 C++大佬 统一都说 C 艹
    elikoi17
        59
    elikoi17  
       2018-12-20 15:06:15 +08:00 via Android
    c 艹没问题
    catror
        60
    catror  
       2018-12-20 15:17:11 +08:00
    v2 已经出现过很多讨论 TCP 粘包的帖子了,到底是哪个半吊子提出来的概念,很想打人。
    字节序这个概念真的太常见了,如果没听说过,可能是一直看的英文资料吧。
    moka20477
        61
    moka20477  
       2018-12-20 15:18:05 +08:00
    虽然我知道他们说的 TCP 粘包是什么意思,大概就是 TCP 分段中含有两个以上 7 层协议的包?
    我觉得认为“粘包”是个问题,还要去解决的人,基本属于完全不懂 TCP...
    SmartKeyerror
        62
    SmartKeyerror  
       2018-12-20 15:42:46 +08:00
    打开家里的水龙头, 看着自来水往下流, 然后你告诉我, 看, 自来水粘在一起了, 不是有病?
    3453452345
        63
    3453452345  
       2018-12-20 15:57:51 +08:00
    看不懂什么叫粘包。
    amosbird
        64
    amosbird  
       2018-12-20 16:14:10 +08:00
    粘包?你怎么不说读文件粘页呢?
    spongebobsun
        65
    spongebobsun  
       2018-12-20 16:34:14 +08:00   ❤️ 1
    @bankroft 句柄表示不服
    paouke
        66
    paouke  
       2018-12-20 16:35:04 +08:00
    TCP 粘豆包吗?
    sgissb1
        67
    sgissb1  
       2018-12-20 16:50:31 +08:00
    lz,你这个调侃过分了。tcp 粘包这个就不是术语,是制造出来的名词。这个词语看上去很形象,但是从传输层角度去说的话,这个形容是很不准确的,tcp 传输过程中现象类似,原因不为一的情况太多了。

    tcp 粘包这个词太含糊
    nbndco
        68
    nbndco  
       2018-12-20 17:21:32 +08:00 via iPhone
    @liuminghao233 这个问题叫 serialization/deserialization
    heiher
        69
    heiher  
       2018-12-20 17:24:20 +08:00 via Android
    函数调( tiao )用
    alienx717
        70
    alienx717  
       2018-12-20 17:28:30 +08:00
    汤姆凯特
    妈啊汶
    一科普利斯\一颗利普斯
    hekunhotmail
        71
    hekunhotmail  
       2018-12-20 17:33:45 +08:00   ❤️ 1
    粘个屁包, 就是收包时,实现不一样的情况出现的伪概念
    popu111
        72
    popu111  
       2018-12-20 17:39:38 +08:00   ❤️ 1
    cache 我很久之前都是读 catch,很艰难地改回来,有时候还是会读错……惭愧
    husinhu
        73
    husinhu  
       2018-12-20 17:55:57 +08:00
    @meik2333 TCP/IP fragmentation/reassembly
    Cbdy
        74
    Cbdy  
       2018-12-20 18:00:09 +08:00 via Android
    TCP 是流,不是包😜
    FrankHB
        75
    FrankHB  
       2018-12-20 18:08:04 +08:00
    cake ……你是不是劣质复读机的受害者……
    不是 cash 吗……
    FrankHB
        76
    FrankHB  
       2018-12-20 18:16:52 +08:00
    @HanMeiM 自从锑度贴吧自动屏蔽艹为*之后,发贴不得不改回来了……

    @reus 字节序还好,整大小端序破事就更多了:

    大小端(endianness)来源是《格列弗游记》,就词源来讲本来就只管“大”“小”端,但是实际上还真有叫 middle-endian 的,就这个不一致的含混含义来讲也是垃圾术语。

    另外,还包括位序……

    (然而维基 byte order 直接重定向到 endianness 上。)
    liuminghao233
        77
    liuminghao233  
       2018-12-20 18:52:25 +08:00 via iPhone
    @nbndco 对的
    myself659
        78
    myself659  
       2018-12-20 19:45:15 +08:00
    流式 就会粘包 科学表达就是无边界
    nmsl
        79
    nmsl  
       2018-12-20 20:00:04 +08:00
    @Earl 写真是日文借词不是音译靴靴
    Mutoo
        80
    Mutoo  
       2018-12-20 20:01:31 +08:00   ❤️ 3
    这个词在网游开发中被创造出来,指在 TCP 协议上输业务数据,利用 TCP 天然的有序顺,将「指令包」按服务端发送的顺序依次送达。但由于 TCP 是流式传输的,所有在缓冲区中会出现不完整的、单个的或多个的指令包。所以业内人士把从缓冲区中的多个连接在一起的指令包称作“粘包”。这个包不是网络层面的 packet,而是业务逻辑层面 packet。
    自然在其它行业看来是无稽之谈了。
    PureWhiteWu
        81
    PureWhiteWu  
       2018-12-20 20:03:25 +08:00
    @Chingim 我知道什么叫贾克斯哈哈哈哈
    kiddult
        82
    kiddult  
       2018-12-20 20:25:32 +08:00
    @liuminghao233 跟业务没关系,TCP 本来就是流,跟包没关系,你又不设计系统,就跟你说河里面的一段水一样。。。。。
    python
        83
    python  
       2018-12-20 20:27:10 +08:00
    ![]( )
    kiddult
        84
    kiddult  
       2018-12-20 20:27:33 +08:00
    @Mutoo 这种指令系统设计从一开始就是废物吧,哪有这么设计协议的,就为了省俩字节?
    blless
        85
    blless  
       2018-12-20 21:12:55 +08:00 via Android
    tcp 粘包的是不是业务层多线程写数据没有处理好…不然怎么可能两个包数据混杂在一起
    crab
        86
    crab  
       2018-12-20 22:17:20 +08:00
    @liuxey 应该是要说应用层上的格式吧。
    ryd994
        87
    ryd994  
       2018-12-21 03:32:58 +08:00 via Android   ❤️ 1
    @blless nagle 算法了解一下
    就算没有 nagle,如果有重传 /重排,接收端程序一下读到两个包的数据,也是很正常的。在应用层就不应该尝试跨层思考到底有几个包。
    如果你需要包边界,可以用 sctp。有顺序有重传,但同时也提供包边界。
    jxl
        88
    jxl  
       2018-12-21 09:03:32 +08:00
    能问到别人,不算啥。能解释的让不知者能听明白,那才是牛。
    lieh222
        89
    lieh222  
       2018-12-21 09:03:54 +08:00
    那是不是 UDP 还有没素质的插队包?
    reus
        90
    reus  
       2018-12-21 09:24:11 +08:00
    @ryd994 你用 socket api 读 tcp,是不会读到重复或者乱序的
    q397064399
        91
    q397064399  
       2018-12-21 09:48:18 +08:00
    @Mutoo #80 业务层面上 其实应该换一个术语 避免跟 底层的概念混淆
    Mutoo
        92
    Mutoo  
       2018-12-21 10:07:49 +08:00
    @kiddult 每个指令包都是 len + payload 并没有省。其实像 websocket 这种也是一样的原理, frame over tcp.
    @blless 粘包是指缓冲区出现两个包接连在一起的情况,不是指数据没处理好。
    @q397064399 这名字不知道哪个年代的大佬起的,后来就一直流传了,改不改不了。
    vipppppp
        93
    vipppppp  
       2018-12-21 10:24:02 +08:00
    我还以为这些科普贴。。。。。。。。
    karllynn
        94
    karllynn  
       2018-12-21 10:25:04 +08:00
    粘包就是扯淡的,说白了就是应用层协议设计
    oldcoder
        95
    oldcoder  
       2018-12-21 11:14:52 +08:00
    将字节流转化成特定的协议?协议没有制定好,编解码器编写不完善,就会发生所谓的“粘包”“拆包”?
    xuanbg
        96
    xuanbg  
       2018-12-21 11:22:05 +08:00
    TCP 怎么没有包?协议本身就是有包这个定义的。
    xfriday
        97
    xfriday  
       2018-12-21 14:10:02 +08:00
    @xuanbg 可惜不是他们说的“粘包”的包
    toinmyfree
        98
    toinmyfree  
       2018-12-21 14:31:50 +08:00
    额,刚看到还以为是红豆小粘包或者紫薯小粘包啥的...
    ryd994
        99
    ryd994  
       2018-12-21 19:18:58 +08:00 via Android
    @reus 你只知其一不知其二。我只是在解释即使没有 nagle,一样可以发生所谓的粘包。

    考虑 123 三个包,2 丢失或者乱序,接收顺序为 132
    收 1 ACK1,没有问题
    收 3 ACK1,这时如果去读,只能读出 1。原则上这时可以丢弃 3。但一般操作系统都会保留 3 以提高效率。由此还产生了 SACK。
    收 2 ACK3,这时如果去读,就会同时读到 23。

    这还是假设程序读取频率远高于包到达的评论的情况。如果网卡有 tso,那还是会二合一。如果应用程序被 deschedule 太久,那还是会二合一。如果应用程序就是太忙,过很久才读,那还是会二合一。
    jiejiss
        100
    jiejiss  
       2018-12-23 15:15:46 +08:00
    “我工作五年的时候也不知道 ‘ TCP 粘包’”
    我还没工作都能看出来你在杠 = =
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5419 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 07:20 · PVG 15:20 · LAX 23:20 · JFK 02:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.