黏包是指网络上有多条数据发送给服务端, 但是由于某种原因这些数据在被接受的时候进行了重新组合, 这就是黏包, 本篇文章用来演示一种最简单的黏包解析方法, 适用于初初初级选手
正常来讲客户端发送给服务端的消息, 都是存在专门的通讯协议的, 为了避免黏包现象, 我们通常有几种方式去制定相应的规则: 消息长度固定, 特定分隔符, 消息长度固定+特定分隔符等
(资料图片)
本文是采用了 特定分隔符的方式, 每条数据包都以 \n结尾
例如以下三条原始数据数据:
hell\n
ningxuan\n
thanks\n
变成了以下两个:
hello\nningxuan\nth
anks\n
这就是黏包
在 socket网络编程中, TCP和 UDP分别是面向连接和非面相连接的. 但是他们都存在产生黏包问题吗?
本文不会对 tcp 和 udp 进行详细的讲解, 感兴趣的可以自行百度或者掘金
先说结论: tcp会产生黏包问题
由于 tcp 协议本身的机制(面向连接的可靠性协议-三次握手机制) 客户端与服务端会维持一个连接(Channel), 数据在连接不断开的情况下, 可以将多个数据包持续不断的发送到服务器上.
但是如果发送的网络数据包太小, tcp就会启用Nagle算法对多个数据包进行合并再发送到服务器上. 这种情况下服务器在接收到消息的时候无法区分哪些数据包是分开的, 所以产生了黏包
还有一种可能是: 服务器在接收到数据之后, 将数据放入到缓冲区中, 如果消息没有被及时的从缓冲区取走, 下次在取数据的时候就会出现一次取到多个数据包的情况, 造成黏包现象
tcp三次握手:
客户端向服务端发送建立通道请求服务端向客户端发送允许客户端建立一个单向的数据通道; 服务端向客户端发送建立通道请求客户端向服务端发送允许服务端建立一个单向的数据通道此时数据通道是双向的, 允许客户端、服务端互相发送消息
Nagle算法:
如果包长度达到 MSS, 则允许发送如果该包中含有 FIN, 则允许发送设置了 TCP_NODELAY 选项, 若所有发出去的小数据包(长度小于MSS )均被确认, 则允许发送若上述条件均未满足, 但发送了超时(一般为 200ms), 则立即发送upd不存在黏包问题
udp本身是无连接的不可靠传输协议, 不会对数据包进行合并发送, 也就没有Nagle算法, 不会存在数据合并的情况, 每一个数据包都是完整的, 所以不存在黏包现象
黏包解析也很简单:
遍历当前的 ByteBuffer 缓冲区判断元素为 "\n" 的下标生成新的 ByteBuffer 缓冲区将起始下标到标记下标的字符写到新的缓冲区具体代码如下所示:
public class ByteBufferTest {
public static void main(String[] args) {
ByteBuffer buffer = ByteBuffer.allocate(32);
buffer.put("hello\nningxuan\nth".getBytes());
split(buffer);
buffer.put("anks\n".getBytes());
split(buffer);
}
private static void split(ByteBuffer buffer){
// 将 buffer 切换为 读模式
buffer.flip();
// 根据 buffer 当前的长度进行遍历
for (int i = 0; i < buffer.limit(); i++) {
// 判断当前下标元素是不是数据包切割符 \n
if (buffer.get(i) == "\n"){ // 注意这个时候 buffer 的 position 属性一直为 0
// 计算当前数据包长度
int length = i + 1 - buffer.position();
// 根据当前数据包长度, 动态生成新的 缓冲区
ByteBuffer target = ByteBuffer.allocate(length);
for (int j = 0; j < length; j++) {
target.put(buffer.get()); // 注意这个时候 buffer 的 position 属性在 ++
}
// 打印 target 当前的元素和属性
ByteBufferUtils.selectAll(target);
}
}
buffer.compact();
}
}
到此这篇关于Netty中最简单的粘包解析方法分享的文章就介绍到这了,更多相关粘包解析内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
标签:
黏包是指网络上有多条数据发送给服务端,但是由于某种原因这些数据在被接受的时候进行了重新组合,本文分享了
2023年泗水“消费提振年·泉民泉心购”新能源电动车零售行业消费券惠民活动的零售商家参与2023年泗水“...
5月16日,记者从2023年二季度全区商务经济暨“破零倍增”推进工作视频调度会上获悉,1—4月,全区商务经...
同样用5G网,有人网速快有人慢,为啥?---自2019年三大运营商推出5G套餐至今已有近四年时间,5G套餐使用感
六旬老人无故流泪原是患上泪道阻塞---长期流眼泪也是一种病哦,你可能是泪道阻塞了!来自二汽的刘大妈(化
魏吉平在沙河市督导调研时强调推进人大信息化建设提升代表履职质效为建设“太行泉城、美丽邢台”作出积...
本网讯(内蒙古日报社融媒体记者张慧玲)5月16日,记者从自治区水利厅获悉,汛期将至,我区各级水利部门开展
1、可以。2、但不可以超过120ml。铁路部门规定,限量携带以下物品:不超过20毫升的指甲油、去光剂、染发剂
想必现在有很多小伙伴对于求高斯奥特曼全集,种子或下载地址都可以方面的知识都比较想要了解,那么今天小好
1、金科廊桥水乡B区位于重庆市沙坪坝大学城,由重庆金科房地产开发有限公司建成,总建筑面积1500000。2、总
1、magnet:?xt=urn:btih:A71478DECB784D9F8580F0D0A0349FBF2DC34A
AI生成新闻女主播美图赏,过于性感让人把持不住了,ai,收视率,美女主播
图①:古庄园的飞檐翘角。图②:“唐氏家祠”祠匾由清代古文学家、岭西五大家之一的王拯所题。图③:庄...
1、在vista直接是不能安装applocale的,主要是因为他不能以“以管理员身份运行”,为甚麼不能呢,是因为它的后序
解答:1、世界上有两种女孩最可爱,一种是漂亮的;一个是聪明,你是个聪明漂亮的女孩。2、我觉得世界上最美
本报讯(记者凌欣炜)“在炎热的天气中坐上凉快的游船,感觉非常棒!”昨天下午,在结束本届苏迪曼...
5月16日,第二十五届上海国际电影节在京召开发布会,会上公布了本届电影节海报、评委会名单,以及其他相关
每经记者:黄辛旭每经编辑:裴健如威马汽车又陷入了新的负面风波。近日,据海南特区报报道,目前,位于海南
题:从围观到体验 类博物馆为民众文化生活添活力中新社记者 徐婧在清代的棋盘上对弈、亲手参与一张
「大牙操作笔记5 16盘后」A股最近出现了缩量震荡调整的趋势,而未来的行情如何发展,需要结合多种因素进行