• 如何解决netty发送消息截断问题


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

                 其实这两条消息应该是一条消息,它们两个才是一个完整的json字符串。查看代码原来是客户端与服务器端都没有考虑TCP粘包与拆包机制。业界主流的解决方案包括:

                (1)消息定长,例如每个报文的大小固定为200字节,如果不够,空位补空格;

                (2)在包尾增加回车进行分割,如FTP协议;

                (3)将消息分为消息头和消息体,消息头包含消息的总长度;

                (4)更复杂的应用层协议

           庆幸的是netty提供了多种解码器用于处理半包问题,开发人员只需要掌握这些类库的使用就很容易处理TCP粘包与半包问题了。下面介绍一下netty常用的解码器: 

                (1) LineBasedFrameDecoder解码器 

           LineBasedFrameDecoder是回车换行解码器,如果用户发送的消息以回车换行符作为消息结束的标识,则可以直接使用Netty的LineBasedFrameDecoder对消息进行解码,只需要在初始化Netty服务端或者客户端时将LineBasedFrameDecoder正确的添加到ChannelPipeline中即可,不需要自己重新实现一套换行解码器。

          LineBasedFrameDecoder的工作原理是它依次遍历ByteBuf中的可读字节,判断看是否有“ ”或者“ ”,如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节就组成了一行。它是以换行符为结束标志的解码器,支持携带结束符或者不携带结束符两种解码方式,同时支持配置单行的最大长度。如果连续读取到最大长度后仍然没有发现换行符,就会抛出异常,同时忽略掉之前读到的异常码流。防止由于数据报没有携带换行符导致接收到ByteBuf无限制积压,引起系统内存溢出。

               (2)DelimiterBasedFrameDecoder

              DelimiterBasedFrameDecoder是分隔符解码器,用户可以指定消息结束的分隔符,它可以自动完成以分隔符作为码流结束标识的消息的解码。回车换行解码器实际上是一种特殊的DelimiterBasedFrameDecoder解码器。

                (3)FixedLengthFrameDecoder解码器

             FixedLengthFrameDecoder是固定长度解码器,它能够按照指定的长度对消息进行自动解码,开发者不需要考虑TCP的粘包/拆包等问题,非常实用。对于定长消息,如果消息实际长度小于定长,则往往会进行补位操作,它在一定程度上导致了空间和资源的浪费。但是它的优点也是非常明显的,编解码比较简单,因此在实际项目中仍然有一定的应用场景。

              (4)LengthFieldBasedFrameDecoder解码器

  • 相关阅读:
    Java8新特性
    为什么要使用ORM技术?和 JDBC 有何不一样?
    HTTP Status 500
    重装Oracle时出现SID已存在问题的解决办法
    数据库模式显示的Swing表格
    自然连接和等值连接
    雷林鹏分享:Java 循环结构
    雷林鹏分享:Java 运算符
    雷林鹏分享:Java 修饰符
    雷林鹏分享:Java 变量类型
  • 原文地址:https://www.cnblogs.com/xingjunli/p/5007985.html
Copyright © 2020-2023  润新知