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. 对象序列化的介绍.......................... ...
随机推荐
- ABAP表生成Java实体Bean
项目中需要将HR模块中的表数据同步到Java系统中,向外围系统提供分发与查询服务,涉及到的表有两百多张,字段好几千上万个,如果手工一张张这些ABAP表在Java系统数据库中创建一遍的话,工作量将非常大 ...
- SQLite在.NET中自适应32位/64位系统
如果一个.NET应用要自适应32位/64位系统,只需要在项目的“目标平台”设置为“Any CPU”.但是如果应用中使用了SQLite,情况就不同了. SQLite的.NET开发包来自是System.D ...
- MyBatis(五):mybatis关联映射
Mybatis中表与表之间的关系分为一下4类: 1)一对一 2)一对多 3)多对一 4)多对多 创建数据Demo表 数据库表: 用户表user:记录了购买商品的用户信息. 订单表orders:记录了用 ...
- 解决Everything1.4版本预览时不支持自定义后缀的问题
2017年6月Everything版本升级到了1.4.x 个人使用下来认为最主要的有以下几点 添加预览功能 搜索结果多选 点击目录列即打开文件所在目录(需要设置:常规->结果->双击路径列 ...
- mybatis 批量添加
<insert id="addTrackBatch" parameterType="java.util.List"> INSERT INTO t_t ...
- 一步步教你轻松学关联规则Apriori算法
一步步教你轻松学关联规则Apriori算法 (白宁超 2018年10月22日09:51:05) 摘要:先验算法(Apriori Algorithm)是关联规则学习的经典算法之一,常常应用在商业等诸多领 ...
- c/c++字节序转换(转)
字节序(byte order)关系到多字节整数(short/int16.int/int32,int64)和浮点数的各字节在内存中的存放顺序.字节序分为两种:小端字节序(little endian)和大 ...
- 使用h2数据库
h2数据库提供了一个简单的web管理界面 import org.h2.tools.Server; import org.slf4j.Logger; import org.slf4j.LoggerFac ...
- java mqtt
代码: package cc.gongchang.mqtt; import java.net.URISyntaxException; import org.fusesource.hawtdispatc ...
- Mac下多版本JDK安装
1.下载 JDK1.6官方未提供1.6的mac版本,需要去apple的开发者网站 JDK1.7.JDK1.8可以去Oracle官方下载 此处提供网盘下载地址: 链接: http://pan.baidu ...