TCP在网络通讯的时候,通常在解决TCP粘包、拆包问题的时候,一般会用以下几种方式:

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

  2、 在消息尾部添加特殊字符进行分割,如添加回车;

  3、 将消息分为消息体和消息头,在消息头里面包含表示消息长度的字段,然后进行业务逻辑的处理。

  在Netty中我们主要利用对象的序列化进行对象的传输,虽然Java本身的序列化也能完成,但是Java序列化有很多问题,如后字节码流太大,以及序列化程度太低等。Jboss的序列化有程度较高、序列化后码流较小。这里利用Jboss的Marshalling测试一个简单的对象序列化。

  新建Maven工程,引入Netty5和Jboss的Marshalling。

  注:这里的Marshalling的版本,如果版本太低,可能会出现消息发送失败的问题。我在测试的时候起先用的是1.3.9,结果就是消息发送失败,打印异常信息发现是空指针的问题。

        <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>5.0.0.Alpha2</version></dependency><dependency><groupId>org.jboss.marshalling</groupId><artifactId>jboss-marshalling-serial</artifactId><version>2.0.0.Beta2</version></dependency>        

  1、服务端

package com.netty.parry.ende4;import com.netty.parry.ende3.MarshallingCodeCFactory;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class Server {public void start(int port) throws Exception {// 配置NIO线程组EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workGroup = new NioEventLoopGroup();try {// 服务器辅助启动类配置ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128).option(ChannelOption.SO_RCVBUF, 32 * 1024).option(ChannelOption.SO_SNDBUF, 32 * 1024).option(ChannelOption.SO_KEEPALIVE, true).childHandler(new ChildChannelHandler());// 绑定端口 同步等待绑定成功ChannelFuture f = b.bind(port).sync(); // 等到服务端监听端口关闭
            f.channel().closeFuture().sync();} finally {// 优雅释放线程资源
            workGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}/*** 网络事件处理器*/private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 添加Jboss的序列化,编解码工具
            ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());// 处理网络IOch.pipeline().addLast(new ServerHandler());}}public static void main(String[] args) throws Exception {new Server().start(8765);}
}

  2、服务端IO处理类

package com.netty.parry.ende4;import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;public class ServerHandler extends ChannelHandlerAdapter {// 用于获取客户端发送的信息
    @Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {// 用于获取客户端发来的数据信息Message body = (Message) msg;System.out.println("Server接受的客户端的信息 :" + body.toString());// 写数据给客户端Message response = new Message("欢迎您,与服务端连接成功");// 当服务端完成写操作后,关闭与客户端的连接
        ctx.writeAndFlush(response);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}
}

  3、客户端

package com.netty.parry.ende4;import com.netty.parry.ende3.MarshallingCodeCFactory;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;public class Client {/*** 连接服务器* * @param port* @param host* @throws Exception*/public void connect(int port, String host) throws Exception {// 配置客户端NIO线程组EventLoopGroup group = new NioEventLoopGroup();try {// 客户端辅助启动类 对客户端配置Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new MyChannelHandler());// 异步链接服务器 同步等待链接成功ChannelFuture f = b.connect(host, port).sync();// 等待链接关闭
            f.channel().closeFuture().sync();} finally {group.shutdownGracefully();System.out.println("客户端优雅的释放了线程资源...");}}/*** 网络事件处理器*/private class MyChannelHandler extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {System.out.println("MyChannelHandler");// 添加Jboss的序列化,编解码工具
            ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());// 处理网络IOch.pipeline().addLast(new ClientHandler());}}public static void main(String[] args) throws Exception {new Client().connect(8765, "127.0.0.1");}
}

  4、客户端IO处理类

package com.netty.parry.ende4;import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;public class ClientHandler extends ChannelHandlerAdapter {// 客户端与服务端,连接成功的售后
    @Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {// 发送消息Message request1 = new Message("666");ctx.writeAndFlush(request1).addListener(new ChannelFutureListener() {public void operationComplete(ChannelFuture future) throws Exception {if (future.isSuccess()) {System.out.println("成功发送到服务端消息");} else {System.out.println("失败服务端消息失败:"+future.cause().getMessage());future.cause().printStackTrace();}}});}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {try {Message response = (Message) msg;System.out.println(response);} finally {ReferenceCountUtil.release(msg);}}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}
}

  5、消息体

package com.netty.parry.ende4;import java.io.Serializable;public class Message implements Serializable{/*** */private static final long serialVersionUID = -5296315429304117678L;private String body;public String getBody() {return body;}public void setBody(String body) {this.body = body;}public Message(String body) {super();this.body = body;}public Message() {super();}@Overridepublic String toString() {return "Message [body=" + body + "]";}
}

  

Netty5+Jboss(Marshalling)完成对象序列化传输相关推荐

  1. Java领域的对象如何传输-了解序列化的意义

    我们发现对User这个类增加一个Serializable,就可以解决Java对象的网络传输问题.这就是今天想给大家讲解的序列化这块的意义 Java平台允许我们在内存中创建可复用的Java对象,但一般情 ...

  2. 让你的对象跑出内存,写入到磁盘或者进行网络传输,一文掌握Java对象序列化

    文章目录 对象序列化是什么 如何让对象可序列化 让对象跑出内存 对象序列化是什么 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络 ...

  3. Netty使用kryo序列化传输对象

    Netty使用kryo序列化传输对象 横渡 Netty使用kryo序列化传输对象 - 简书参考文章:https://blog.csdn.net/eguid_1/article/details/7931 ...

  4. JBoss Marshalling编解码

    一.简介 JBoss Marshalling是一个Java对象序列化包,对JDK默认的序列化框架进行了优化,但又保持和java.io.Serializable接口的兼容. 二.Marshalling开 ...

  5. python对象序列化

    这篇文章主要介绍了Python中的序列化存储的方法,序列化存储主要针对的是内存和硬盘之间的写入操作,需要的朋友可以参考下 在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: ? 1 ...

  6. Java学习总结:51(对象序列化)

    对象序列化 对象序列化的本质实际上就是将内存中所保存的对象数据转换为二进制数据流进行传输的操作. 但并不是所有类的对象都可以直接进行序列化操作,要被序列化的对象所在的类一定要实现java.io.Ser ...

  7. java培训教程分享:Java中怎样将数据对象序列化和反序列化?

    本期为大家介绍的java培训教程是关于"Java中怎样将数据对象序列化和反序列化?"的内容,相信大家都知道,程序在运行过程中,可能需要将一些数据永久地保存到磁盘上,而数据在Java ...

  8. .NET 中的对象序列化 (转载)

    .NET 中的对象序列化 Piet Obermeyer Microsoft Corporation 2001 年 8 月 摘要:为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便 ...

  9. java 对象怎么序列化,java对象序列化总结

    java对象序列化小结 百度百科上介绍序列化是这样的: 序列化 (Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储 ...

  10. WCF入门(三)——对象序列化

    对象序列化 WCF是通过网络实现远程方法调用的,因此参数,返回值等都需要序列化才能在网络间传输.例如,对于下面的一个服务: [ServiceContract]     public interface ...

最新文章

  1. 72岁奶奶在抖音教物理火了,百万粉丝追更,网友:小时候要有这种老师就好了...
  2. linux 命令整理(持续更新)
  3. ASA 9.21 in Vmware Workstation 10
  4. Mono for Unreal Engine发布,C#进入虚幻引擎(Unreal Engine)
  5. Python+pandas处理Excel文件案例一则
  6. word度量单位无效_【一定要看】这篇Word毕业论文排版全攻略,25个技能请收藏好~...
  7. 【小知识点】分类机器学习中,某一标签占比太大(标签稀疏),如何学习?...
  8. PE-2 暴模...
  9. [文档]CSS中文字体对照表
  10. 如何在VS2015创建C语言项目
  11. html微软雅黑无效,移动端h5不支持font-family里面的楷体、微软雅黑等字体
  12. Failed to start SYSV: NGINX is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server.
  13. 15岁黑客Cosmo的堕落历程
  14. 支付宝小程序 使用uView实现省市区三级联动的后续
  15. 阿里云智能接入网关体验
  16. C++:C++编程语言学习之数学运算运算符及其优先级的简介、案例应用之详细攻略
  17. 【商品架构day2】一个商品的领域模型长什么样子 - 淘宝十多年前的认知
  18. Week4 常用类 麻了
  19. 多媒体个人计算机能处理什么,多媒体计算机可以处理的信息类型有什么?
  20. 机器学习【西瓜书/南瓜书】--- 第1章绪论(学习笔记+公式推导)

热门文章

  1. python交互式程序设计导论第三周小测验答案,2020学堂云Python 交互式程序设计导论答案第五章节答案...
  2. hbuilder简单网页模板_网页设计公司有哪些?用这个快速建站!
  3. VS debug调试时提示“未找到源”
  4. C# Json、datatable、model互相转换
  5. 微信小程序报错 TypeError: Cannot read property ‘setData‘ of undefined
  6. 专题三:MATLAB程序流程控制
  7. 对目录下所有库文件进行rpath更改操作的SHELL脚本
  8. 面试疑点:几道题答了一个小时,应该是等答案
  9. 文字处理技术:文字形状绕排不是挺简单的事吗,怎么搞得这么复杂
  10. 自己SSD近来经常掉盘,一看这一段时间SSD涨价很多啊