如何解决netty发送消息截断问题
在netty开发过程中我遇到过长的消息被分割成多个小消息的问题。如下图所示:

其实这两条消息应该是一条消息,它们两个才是一个完整的json字符串。查看代码原来是客户端与服务器端都没有考虑TCP粘包与拆包机制。业界主流的解决方案包括:
(1)消息定长,例如每个报文的大小固定为200字节,如果不够,空位补空格;
(2)在包尾增加回车进行分割,如FTP协议;
(3)将消息分为消息头和消息体,消息头包含消息的总长度;
(4)更复杂的应用层协议
庆幸的是netty提供了多种解码器用于处理半包问题,开发人员只需要掌握这些类库的使用就很容易处理TCP粘包与半包问题了。下面介绍一下netty常用的解码器:
(1) LineBasedFrameDecoder解码器
LineBasedFrameDecoder是回车换行解码器,如果用户发送的消息以回车换行符作为消息结束的标识,则可以直接使用Netty的LineBasedFrameDecoder对消息进行解码,只需要在初始化Netty服务端或者客户端时将LineBasedFrameDecoder正确的添加到ChannelPipeline中即可,不需要自己重新实现一套换行解码器。
LineBasedFrameDecoder的工作原理是它依次遍历ByteBuf中的可读字节,判断看是否有“\n”或者“\r\n”,如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节就组成了一行。它是以换行符为结束标志的解码器,支持携带结束符或者不携带结束符两种解码方式,同时支持配置单行的最大长度。如果连续读取到最大长度后仍然没有发现换行符,就会抛出异常,同时忽略掉之前读到的异常码流。防止由于数据报没有携带换行符导致接收到ByteBuf无限制积压,引起系统内存溢出。
(2)DelimiterBasedFrameDecoder
DelimiterBasedFrameDecoder是分隔符解码器,用户可以指定消息结束的分隔符,它可以自动完成以分隔符作为码流结束标识的消息的解码。回车换行解码器实际上是一种特殊的DelimiterBasedFrameDecoder解码器。
(3)FixedLengthFrameDecoder解码器
FixedLengthFrameDecoder是固定长度解码器,它能够按照指定的长度对消息进行自动解码,开发者不需要考虑TCP的粘包/拆包等问题,非常实用。对于定长消息,如果消息实际长度小于定长,则往往会进行补位操作,它在一定程度上导致了空间和资源的浪费。但是它的优点也是非常明显的,编解码比较简单,因此在实际项目中仍然有一定的应用场景。
(4)LengthFieldBasedFrameDecoder解码器
如何解决netty发送消息截断问题的更多相关文章
- Netty 发送消息失败或者接收消息失败的可能原因
1. 消息发送失败: 检查通道是否建立成功 Netty中的通道建立采用的是异步方式,获取到的通道对象可能为空或初始化未完成: 2. 接收的消息有丢失 消息可能会粘包,是否有拆包机制
- Netty开发redis客户端,Netty发送redis命令,netty解析redis消息
关键字:Netty开发redis客户端,Netty发送redis命令,netty解析redis消息, netty redis ,redis RESP协议.redis客户端,netty redis协议 ...
- Android 基于Netty的消息推送方案之字符串的接收和发送(三)
在上一篇文章中<Android 基于Netty的消息推送方案之概念和工作原理(二)> ,我们介绍过一些关于Netty的概念和工作原理的内容,今天我们先来介绍一个叫做ChannelBuffe ...
- Netty客户端发送消息并同步获取结果
客户端发送消息并同步获取结果,其实是违背Netty的设计原则的,但是有时候不得不这么做的话,那么建议进行如下的设计: 比如我们的具体用法如下: NettyRequest request = new N ...
- 【转】解决Maxwell发送Kafka消息数据倾斜问题
最近用Maxwell解析MySQL的Binlog,发送到Kafka进行处理,测试的时候发现一个问题,就是Kafka的Offset严重倾斜,三个partition,其中一个的offset已经快200万了 ...
- 解决c#所有单线程单元(STA)线程都应使用泵式等待基元(如 CoWaitForMultipleHandles),并在运行时间很长的操作过程中定期发送消息。 转载
最近做一个后来程序,启动了事务后有一段操作业务,当运行一段时间后,出现这个异常 CLR 无法从 COM 上下文 0x1b1c38 转换为 COM 上下文 0x1b1da8,这种状态已持续 60 秒.拥 ...
- Netty框架问题记录1--多线程下批量发送消息导致消息被覆盖
业务背景 项目是基于Netty实现的实时课堂项目,课堂中老师需要对试卷进行讲解,则老师向服务器发送一个打开试卷信息的请求,服务器获取试卷信息,将试卷信息发送给所有的客户端(学生和老师). 发送给学生的 ...
- 解决QQ“抱歉,无法发起临时会话,您可以 添加对方为好友以发送消息”
很多网站,目前无法发起临时会话,自己在找网上找到教程,特分享给大家.自从2014年3月1日开始,网站上放置QQ客服代码的网站,在点击联系QQ时,以前可以正常发起临时会话的,现在提示:“抱歉,无法发起临 ...
- 记一次解决netty半包问题的经历
最近学习了netty,想写一个简单的rpc,结果发现发送消息时遇到难题了,网上搜了一下,这种情况是半包问题和粘包问题,主要是出现在并发高一些的时候. talk is cheap 客户端编码: prot ...
随机推荐
- java后台判断发布的图片是否存在
x现在已知一个固定格式的图片,判断图片是否存在例如,http://127.0.0.1/image/201709091300.jpg import java.net.URL;import java.ne ...
- SPOJ1811 LCS SAM
后缀自动机简单题. 其主要思路是,先对第一个字符串建立后缀自动机,把第二个串放在上面匹配, 若当前状态s有字符x的转移,直接转移len=step+1. 若当前状态s没有向字符x的转移,退回pres检查 ...
- 物体position:absolute后设置left:50%发生的有趣小事
今天在重构ui控件中3秒hint提示框样式,发现了一个有趣的小事,特发个文章记录一下,方便自己日后看一下 一 准备知识 ①一个已设置宽高的块状元素设置position:absolute后会保持他原来宽 ...
- OpenGL之坐标转换(好文-清晰版)
http://blog.csdn.net/zhongjling/article/details/8488844OpenGL之坐标转换(好文-清晰版)
- XML中CDATA和#PCDATA的区别
在XML文档中, 能看到“CDATA"的地方有三处: 1)在DTD中,指定标签中某个属性的类型为字符型时,使用CDATA.因为XML解析器会去分析这段字符内容,因而里面如果需要使用>, ...
- poj 3617 Best Cow Line 解题报告
题目链接:http://poj.org/problem?id=3617 题目意思:给出一条长度为n的字符串S,目标是要构造一条字典序尽量小,长度为n的字符串T.构造的规则是,如果S的头部的字母 < ...
- 避免复杂的layout
layout是浏览器计算元素的几何信息:元素在页面上的的大小和位置. 每个元素都有明确的亦或含蓄的大小信息,这些信息基于我们使用的css以及元素的内容被高和父亲元素. 这个过程在 Chrome, Op ...
- 基于Jenkins+Gitlab的自动化部署实战
故事背景 一个中小型企业,是典型的互联网公司,当初期的时候可能运维只能标配到2~3人,此时随着公司的发展,项目会逐渐增多.前期部署项目可能都是手动的, 俗称“人肉部署”,这简直是无比的痛苦,不能忍受的 ...
- @PathVariable @RequestParam @RequestHeader @CookieValue POJO Servlet API
- python虚拟环境管理包virtualenvwrapper
1.打开cmd 2.安装virtualenvwrapper pip install virtualenvwrapper-win 3.配置虚拟环境的位置 新建系统变量默认在c盘 4.新建虚拟环境 mkv ...