分享文章: TCP 粘包? TCP 警察什么梗
文章地址:TCP 粘包? TCP 警察什么梗
从 v2 学到很多,按照自己理解总结了下。0.0
讲拆包粘包的很大比例是 Javer ,Netty 权威指南功不可没…
TCP 粘包?伪命题,tcp 从来不是像 UDP 一样,以包设计的,而是流式的,就像滔滔不绝的流水一样。
有请双方选手入...哦 2L 已经入场一位!
好久没有这个话题了,恭喜 lz 找到了热点
警察看了头疼
粘包一词到底是怎么造出来的,我很是好奇
PS 每每看到粘包警察一词就想笑
粘念 zhān 还是 nián ?
原封不动的把一篇文章看完了,耗时 10 分钟。
警察已经开始摆烂了
TCP 粘包是啥? 自己创造一个名词出来? TCP 从来没有粘包一说, 看你的文章你也是对 TCP 一知半解。 麻烦赶紧删了,免得误人子弟。
我先跟你说,很明确的来说 TCP 没有粘包这一个说法,根本就不存在。
我看你用 Java 写的代码, 那么我就用 Java 代码给你举个例子
Socket socket = new Socket("127.0.0.1", 8000);
OutputStream os = socket.getOutputStream();
os.write("test".getBytes());
实际上会发生什么?
如果网络延迟,或则发生丢包,那么会超时重传. 然后网络线路没问题, 那么会直接写入系统的 TCP/IP buffer 里面去。
如下
Socket socket = new Socket("127.0.0.1", 8000);
OutputStream os = socket.getOutputStream();
os.write("test".getBytes());
os.write("test1".getBytes());
os.write("test3".getBytes());
那么我写入三次表示什么? 很显然根据我上面说的,系统为了性能会缓存对应的 TCP/IP 的数据信息, 那么我可以采用一个很大 buffer 来进行一次性将这两次的请求给直接读取过来。
根据这个理解那么就可以把 TCP 看作流, 通过流来进行运输货物,很显然明显的是 TCP 就是流协议。 流协议何谈封包和拆包?
那如何解决判断 TCP 中这次请求的信息已经是末端了?
很常见的两种方案
- 一次请求一次响应, 后续关掉 socks
- 用 4 字节定义一个无符号的整数来定义这个报文的 Length 就好了
所谓的 特殊分隔符
简直是最愚蠢的做法, 难道我的报文中就不能出现对应的特殊符号吗? 固定消息长度
简直是浪费内存和网络开销。完全不可取。
因为是流协议, 所以需要应用自己去判断写入的字节什么时候已经达到的末端。
其实这块儿的中文术语很模糊,报文、帧、数据包啥的,用英文表达会好一点。
有的书把 packet 翻译成报文,有的把 message 翻译成报文,服了…
建议 op 看看
draveness.me/whys-the-design-tcp-message-frame/
热帖预订。顺便提示楼主,还有一个流量密码:HTTP 状态码一律 200 、HTTP 请求方式一律 GET/POST
无所谓了,只要你能听明白, 需要一个上层协议来拆分信息就行
前一阵子有个沙雕,非要我发送的时候,给他拆好 .dog
我接收的怎么是这样子 .jpg
你那里有问题 .jpg
不是我的问题 .jpg
不是我负责的 .jpg
你前端改改 .jpg
TCP: 我把东西按顺序给到你了,我们也不知道你们发的啥玩意儿,自己看吧
当我看到 TCP 粘包的时候,我很震惊, 后面我开始解释 TCP 没有粘包, 只有 “因为是流协议, 所以需要应用自己去判断写入的字节什么时候已经达到的末端。” 后来我渐渐的麻木......
TCP 粘包就是理论上不存在但实际上必须处理的东西 /狗头
这页面上乱七八糟的元素,我还以为我打开了内容农场
死去的回忆开始攻击我
packet frame message
跨频道聊天是吧
四层传输层 TCP 协议流式,七层应用层通过缓冲区映射成数据包处理,说粘包并没错。但是“粘包”这个词是生造的,用于新手快速理解还可以,再深入点就该换成“分帧取帧”,或者“帧解码”。
#21 你确定你理解的是楼主所说的问题, TCP 帧在应用层是不关心的。 而所谓的 “判断写入的字节什么时候已经达到的末端” 是需要自己解析的
而且你说的 “分帧取帧”,或者“帧解码”。 是指什么? 说的是 解析 RFC 793 里面的 TCP Header Format
吗? 很抱歉,在用户使用协议上,没有权限读取对应的 TCP Header Format
, 要么使用 tun/tap 等虚拟网卡, 要么使用 pcap/winpcap/npcap 或则 win10 的驱动网络拦截。 但是这些 TCP 协议的操作,往往都不是 TCP 使用用户来进行操作的, 楼主很明显是在使用 TCP 协议, 而不是解析 TCP 协议
什么叫字节文化啊(后仰
HTTP1.0 好像就是根据 connection:close ,来判断 HTML 是否已经完全传输完毕。
也不是所有的 TCP 都有 content-length 属性,在那个 IE 时代,经常遇见下载到一半的网页突然断开。
在 TCP 这层不用考虑这个
TCP 有所谓的“粘包”是使用情景出错了,你把两个以上的数据报放在一个 tcp 流里面传输了;正常的应该是一个“包”一个连接。像 HTTP 的长连接就是这种情况,不过 HTTP header 有 length 可以解决“粘包”
#22 网络通信是七层,不要死扣在传输层 TCP 协议这一个上。帧的英文是 Frame 。还有不要再回复了,这贴是给楼主的内容农场引流的,正方反方意见都不重要,都会给楼主引流。
他们说的 tcp 粘包,应该是指 nagle 算法吧。。
/go/water
TCP 没有包,但是这篇文章非要把指出这个事实的人扣一个“粘包警察”的帽子,似乎还有点得意。
基于错误的概念讨论一大堆东西都是没有意义的。
就这篇文章来说,TCP 的包是啥它自己清楚吗?
是你调用一次 socket write 的数据,还是 wireshark 抓包看到的一个 TCP 的条目?还是你应用层自己定义的逻辑结构?
概念都不定义清楚就自说自话,就是一堆废话。
掘金在某些人看来已经是内容农场了么 哈哈哈
国内要啥社区生态啊
就喜欢看这种话题,掐!打起来!别停手!
小马扎、花生米已经就位啦!
奥山 YY 来人
之前也看过很火的几个黏包警察的帖子
面试的时候也被问过 大概就是解决黏包的方案 比如
其实说的不是报文粘包,而是消息解析的问题
我不管,我的 TCP 就是要粘包[手动狗头]
TCP 只保证可靠数据传输,没说把数据一个个拆开好给你,这件事应该由上层协议负责处理。
如果是这样的话,你也可以提出这样一系列问题:
如何解决 IP 协议不能可靠数据传输的问题?常规解决方案是用 TCP ;
如何解决 Ethernet 协议与全球服务节点连接问题?常规解决方案是使用 IP 协议;
...
回过头来看,这正是「分层」思想的奥义所在啊,每一层只处理好自己的事儿。
·粘包·真是误人子弟,还有一大堆捧的,还在那里抠概念,错的就是错的
和 nagle 没任何关系。无论怎样,接收端读都可能会读取不定次数写的内容。
我无法理解这里在嘲讽 tcp 粘包的什么问题。这确实是工程中需要处理的内容。
这解释到位,可以。
好几年前我一直认为 tcp 粘包是一个非常复杂的事情,一直没认真去看,后来要面试就专门去看 TCP 粘包。tmad 差点颠覆我的认知,这算个屁粘包,不知道哪个土鸡 提出来的。后来终于看到 V2 原来也有很多人不认可这个事情,那我就放心了,原来我的认知没错,某些人的问题。。。
生造词只会把问题弄得更复杂,明明很简单的原理,一句话就能说清楚的事情,非要生造一个词,然后再写一篇文章来解释这个词,把问题弄得更复杂。
还有,你说人家是“tcp 警察”,我觉得你是“tcp 恐怖分子”
#1 javer 表示不背这个锅
tcp 流式传输哪来的包, 脑袋里长了个包吗...
这种情况也不能叫 tcp 粘包, 叫应用层粘包才对.
这就是中文 cs 界的恶心之处,总是发明一些莫名奇怪的称呼。英文 tcp framing tcp stream 就很直观
十年前看网络编程书籍的时候有“tcp 粘包”的说法,其实是说需要一个业务协议去分包,比如:length + body 的格式,懂得都懂,每天没事做就拿出来喷一次,何必呢
粘包 难道不是“碰瓷”的意思? emmmm, 这个标题我都没看懂......TCP 警察......你再说某夫网?
早上看到帖子乐了,以为大家会调侃一下粘包警察的耿
结果。。哈哈哈
看到“TCP 粘包”这个专有名词,我表示极度震惊。连夜打车回到家里,战战兢兢翻开《计算机网络》,拿着放大镜仔细看了半夜,也没看到“粘包”两个字。我的后背不觉地渗出致密的汗水,双手止不住地发抖。匆忙打开电脑,一篇篇地翻着论文,试图寻找关于这个词的信息。可眼看天就要亮了,我依旧一无所获。我失望的躺在床上,满脑子都是“粘包,粘包,粘包!”,横竖睡不着,不得已打开了知乎,写下了一个问题“究竟什么是 TCP 粘包”。不一会儿答案就如雪花儿般涌了出来,每一片雪花上都写着一句话“TCP 没有粘包”。我颤抖的双手终于停了下来,一股热流从我心底涌到泪腺。啊,原来我并不孤独。
讨论一个东西的前提是得有定义,谁来定义这个 TCP 的包概念?其次,同样是流式读写,没有人会在读写文件的时候说有粘包问题吧?
哈哈哈哈,每年都有几次粘豆包。[头秃]
建议粘豆包用户都改用 websocket
掘金已经和内容农村差不多烂了
某种意义来说,楼主已经成功了,确实吵起来了 (doge
#7 nian 是形容词,大 nian 鼻涕;
zhan 鼻涕 zhan 手上甩不下来; zhan 胶带。
所以应该是 zhan 包,
nian 豆包
TCP 确实有“粘包”问题。
所以为什么要死磕 TCP ?找个 TCP 上层的、有“消息”概念的协议不好嘛?比如 WebSocket ?
我有些反感粘包警察,是因为早就被标准化解决了无数遍,直接拿来就能用(比如 WebSocket 这个五层协议)的问题,非要当做现实中一个重大问题去翻来覆去地讨论。
分包组包这是网络层干的事情, 跟传输层有什么关系.
看 ip 协议有个分包组包, 然后造个 tcp 的拆包黏包, 真的是恶心啊, 很容易把基础不行的人带歪.
#56 tcp 都没有包这个概念, 怎么会 粘和拆 呢
nnmlgbb
WebSocket 属于第五层?那么为什么握手要基于 HTTP 。
搜了下,OP 文章提的都是网络上很多年就有的名词和争议, 怎么都在骂楼主扣帽子。。
不是看起来是,而是他已经在朝这方面做,用 Google 搜一下 site:juejin.cn inurl:/s/ 你就能体验到了
嗯我确实说错了,在通用模型里面属于第四层应用层。HTTP 和 WebSocket 都属于应用层。
另外如果看 HTTP 和 WebSocket 的关系,实际上 WebSocket 可以独立于传统的 HTTP 服务器单独使用,只不过 Handshake 这一步好像用了 HTTP header 。但如果一整个端口都用于 WebSocket 应用程序的话,其实可以忽略 HTTP 协议这玩意儿。
WebSocket 单独使用,你可以参考币的交易所协议。
吗吗,你的言论有些“反粘包警察”哦。
所以其实我“粘包”打引号了。虽然 TCP 确实不存在粘包这个概念,但是在应用中这个“问题”确实存在。我是不关心这玩意儿到底用“粘包”这个术语,还是准确地“因为 TCP 是流式协议所以必须自己处理数据包分割的问题”这么长的文本描述。在我看来,入乡随俗,如果“粘包”接受度广,用“粘包”来代指上面这句话我没意见。
http 1.0 是靠 tcp connection close 来识别的; 1.1 才有 content-length 和 transfer-encoding chunked 这两个功能
谷歌翻译给这个字的音标是 /Zhān/,点发音念的是 nian ,笑死了
#64 所以如果叫 基于 tcp 传输的应用层消息拆分 我是没意见的, 非要叫个 tcp 拆包, 纯属误人子弟
诶?难道不是吗?
“你们不要再打了啦”
#64
我告诉你粘包是怎么来的
Socket socket = new Socket("127.0.0.1", 8000);
OutputStream os = socket.getOutputStream();
os.write("test".getBytes());
os.write("test1".getBytes());
os.write("test3".getBytes());
写了三次数据, 然后在调用 read 读取的时候发现写入的数据被一次性读取到了, 所以他 /她认为数据包被粘连在一起了。
“粘包” 无论是否打引号说出这个词就是对 TCP 协议的不理解,想当然的一个词语。 这种本身就应该抵制。"需要自己判断写入的字节什么时候已经达到的末端", 这就很好的解释了这个问题。
我没猜错你对 TCP 协议估计也是一知半解 。你写一次 tun 设备的 三次握手和四次挥手, 你就知道所谓的封包 /拆包 /重传 等等, 都已经做好, 数据已经有序的给你了。 你只要操作 Stream 就可以了。
我在跟你明确一下, 他说的粘包,指的是 代码中 write 两次, 另一端 read 一次的时候就可以读出来。
或则我这么问你, 如果你发现 TCP 有所谓的粘包, 请截图用 wireshark 抓包并且保存截图让我看看, 你能截屏出来, 我给你奖励 1w
把协议设计好基本不会出现所谓的“粘包”
#敏感词 有没有可能,你说的这个东西接受度最广的叫法是「协议」。
查重率百分之百
所谓的特殊分隔符
简直是最愚蠢的做法
http header 就是靠\n\n....
所谓“粘包问题”不就是设计一个应用层协议的问题么?在 TCP 协议(传输层)的范畴中,问题不存在就不是不存在...
我不否认粘包实际不存在。我知道 TCP/IP 。但我觉得既然这么多人叫,那在别人都这么叫的语境下,借用这个术语表达他们的意思,我没意见。。。
为啥要这么纠结术语的纯洁性。DL 论文里面一堆(数学)术语乱用,只要该 domain 认同,不也就这么过来了。
不知道在吵吵啥,听得懂就行,非 BB 半天你这概念不对,描述不对
/t/876279
http 是靠\r\n\r\n 吧。不是\n\n 吧?
别纠结“粘包”这个词翻译对不对,令我震惊的是大多数人好像都不知道这回事
不用'特殊分隔符'的话,还有其他好法子吗?
TCP 粘包,UDP 汤包,ICMP 叉烧包
那 tcp 没有粘包,upd 也没有粘包,粘包这个词是怎么来的?😵
#74L
我从未听过 http 协议中用 \n\n 来最为判断文本已经达到的末端。 根据 http 协议 content-length
用来判断数据大小是多少, 即使在早期也是 一次请求,一次响应, 用 tcp connection close 来识别的。 请问你说 的 \n\n 是哪个版本?
#83
说白了就是没有了解 tcp 的原理,没有了解流的概念,导致了 “发送两次,却一次就能全接收了”。
也就是 “我明明辛辛苦苦把数据分成两次(“他认为这是两个包”)发送,怎么一次就全接收了,肯定是 tcp 协议把我的两个 ‘包’ 粘在一起了” ,所以有了 “tcp 粘包” 这个概念。但是对于 tcp 来说是没有包的这个概念的,是发明 “粘包” 的这个人没有了解 tcp 原理导致的。
同理,如果一个人只知道流,没有包的概念,那他遇见 udp 就会产生“udp 拆包”,tcp 是保证顺序的,udp 不保证,他还会产生“udp 乱流”的概念,因为不知道一个东西怎么用就强行用会导致无数个“xx 问题”的概念,但是这些概念本身没有什么意义,因为如果一开始就了解一下什么是流,“粘包”这个概念根本就不会产生。
楼上有人纠正过了,是\r\n\r\n.... 这个分隔符用来分割 http header 的 content 的
一个个都在 纠正 TCP 没有粘包, 我看了就头疼,为什么你们接受不了这个形容词呢? 如果你们要纠正,那就请你拿出正确的形容词出来(必须是业内认可,通用的,不能是自己造的)。
无论你们认不认,有一个事实 已经是既定的了, 那就是听到 TCP 粘包,大家就知道 是接收端 读到了数据,但是数据里 不止一条消息,需要自己去拆分出来。 粘包这个形容词 已经是业内通用了的, 你们非要来纠正,但是又拿不出真正通用的 形容词。
恕我直言,这种行为叫抬杠。
正确的叫法是“一种对协议进行错误解析的方式”
RT,电脑不关机,CPU 占用并不高,很少超过 50%,内存占用通常在 70%以上,偶尔会接近 90%,用上几天后会出现鼠标间歇性卡顿,音乐播放间歇性卡顿,输入法间歇性卡顿然后…
大家好,mac 上有哪款 git GUI 工具好用呢? 最好是带中文的,主要是给策划用。 感谢大家回复,有些人推荐命令行,IDE 这种, 这种方式对程序员友好,但是对非程序员…
Electron 不考虑,没见过用 Electron 写的用户体验好的程序,公认优化好的 VS Code 启动也很慢,剩余内存一不够就卡得要死。 目前是有一点 C++ Qt 和…