Netty5+Jboss(Marshalling)完成对象序列化传输
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> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// 添加Jboss的序列化,编解码工具
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
// 处理网络IO
ch.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 { // 用于获取客户端发送的信息
@Override
public 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);
} @Override
public 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> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
System.out.println("MyChannelHandler");
// 添加Jboss的序列化,编解码工具
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
// 处理网络IO
ch.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 { // 客户端与服务端,连接成功的售后
@Override
public 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();
}
}
});
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
Message response = (Message) msg;
System.out.println(response);
} finally {
ReferenceCountUtil.release(msg);
}
} @Override
public 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();
} @Override
public String toString() {
return "Message [body=" + body + "]";
}
}
Netty5+Jboss(Marshalling)完成对象序列化传输的更多相关文章
- netty: marshalling传递对象,传输附件GzipUtils
netty: marshalling传递对象,传输附件GzipUtils 前端与服务端传输文件时,需要双方需要进行解压缩,也就是Java序列化.可以使用java进行对象序列化,netty去传输,但ja ...
- netty 对象序列化传输示例
package object.server.impl; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Chann ...
- netty: 编解码之jboss marshalling, 用marshalling进行对象传输
jboss marshalling是jboss内部的一个序列化框架,速度也十分快,这里netty也提供了支持,使用十分方便. TCP在网络通讯的时候,通常在解决TCP粘包.拆包问题的时候,一般会用以下 ...
- netty系列之:使用Jboss Marshalling来序列化java对象
目录 简介 添加JBoss Marshalling依赖 JBoss Marshalling的使用 总结 简介 在JAVA程序中经常会用到序列化的场景,除了JDK自身提供的Serializable之外, ...
- netty 的 JBoss Marshalling 编码解码
一. JBoss Marshalling 简介. JBoss Marshalling 是一个Java 对象序列化包,对 JDK 默认的序列化框架进行了优化,但又保持跟 Java.io.Serializ ...
- netty权威指南学习笔记八——编解码技术之JBoss Marshalling
JBoss Marshalling 是一个java序列化包,对JDK默认的序列化框架进行了优化,但又保持跟java.io.Serializable接口的兼容,同时增加了一些可调参数和附加特性,这些参数 ...
- Java对象序列化剖析
对象序列化的目的 1)希望将Java对象持久化在文件中 2)将Java对象用于网络传输 实现方式 如果希望一个类的对象可以被序列化/反序列化,那该类必须实现java.io.Serializable接口 ...
- C#对象序列化与反序列化zz
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍........................ ...
- C#对象序列化与反序列化
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍.......................... ...
随机推荐
- Vue(三)常用指令
(1) v-model 双向数据绑定,一般用于表单元素 <script> window.onload=function(){ new Vue({ // el:'.itany', el:'d ...
- px2rem
vue做移动端适配,借助px2rem 插件方便的将px单位转为了rem 1.安装 npm install px2rem-loader lib-flexible --save 2.在项目入口文件mai ...
- poj3669 Meteor Shower(预处理+bfs)
https://vjudge.net/problem/POJ-3669 先给地图a[][]预处理每个位置被砸的最小时间.然后再bfs. 纯bfs,还被cin卡了下时间.. #include<io ...
- [Nuget]使用Nuget管理工具包
摘要 这里演示如何使用Nuget对类库进行打包,并将类库上传到nuget上面. 步骤 1.在nuget官网注册账号,并登陆. https://www.nuget.org 2.下载Nuget.exe,并 ...
- hadoop ha 读取 activce状态的活动节点
方式一 package com.xxx.hadoop; import com.sun.demo.jvmti.hprof.Tracker; import com.sun.xml.bind.util.Wh ...
- Redis简单示例
1.Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 从2010年3月15日起,Redis的开发工作由VMwa ...
- Quartz定时器中Cron时间控制表达式写法
Quartz定时器中Cron时间控制表达式写法: 1.表示形式 该表达式简洁简单,总共有7个空格分割的表达子式,形式为[* * * * * * *],而这七个位置上的东西表达方式有很多,意义从左往 ...
- [Java] zjdbcping:JDBC数据库连接测试工具
作者: zyl910 一.缘由 当数据库服务器很多时,或者要与第三方公司做数据库表交换时,此时觉得若有一个简单快捷的数据库连接测试工具就好了. 因为若是采取直接把程序部署到tomcat等容器再测试的办 ...
- Android 异常 android.os.NetworkOnMainThreadException
近期在实现一个Android下的数据採集的SDK,收集用户使用数据使用HTTP发送到云平台.进行数据分析.但在发送数据时报例如以下错误: Caused by: android.os.NetworkOn ...
- vue-resource和vue-async-data两个插件的使用
vue-resource和vue-async-data两个插件的使用,看了一下文档http://cn.vuejs.org/guide/plugins.html#u5DF2_u6709_u63D2_u4 ...