传输会话简要

客户端发起一个文本请求给服务器端, 服务器端解析里面文本, 返回文件给客户端, 客户端解析文件

服务器端

因为示例文件比较小, 所以没有做分段传输, 而是直接一次性把整个文件byte[]都发给客户端了.

如果需要传输大文件, 则需要做粘包拆包, 参考另外一篇博文 Netty之粘包分包

需要三个ChannelPipeline

                             // 解析客户端发送的文本json
pipeline.addLast(new StringDecoder());
// 二进制文件加密传输
pipeline.addLast(new ObjectEncoder());
// 业务逻辑
pipeline.addLast(new FileServerHandler());

FileServerHandler业务逻辑

            // 获取到客户端请求, 解析path, 返回二进制文件
JSONObject jo = new JSONObject(msg.toString());
if (StringUtils.isNotEmpty(jo.optString("path"))) {
PDFContent pdf = new PDFContent();
byte[] content = com.fr.general.IOUtils.inputStream2Bytes(new FileInputStream(jo.optString("path")));
pdf.setContent(content);
ctx.writeAndFlush(pdf);
} else {
System.out.println(jo.optString("res"));
}

客户端

跟服务器端对应的三个ChannelPipeline

                             // 传输文本给服务器端
p.addLast(new StringEncoder());
// 二进制文件获取解析
p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(this
.getClass().getClassLoader())));
// 客户端业务代码
p.addLast(new FileClientHandler());

FileClientHandler业务逻辑

         @Override
public void channelActive(ChannelHandlerContext ctx) {
try {
// 将要获取的pdf路径发送给服务器端
JSONObject jo = JSONObject.create().put("path", "d:\\a.pdf");
ctx.writeAndFlush(jo.toString());
} catch (JSONException e) {
e.printStackTrace();
}
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
PDFContent content = (PDFContent) msg;
// 从服务器端获取的二进制文件存到本地
String fileName = UUID.randomUUID().toString() + ".pdf";
File file = new File("D:\\" + fileName);
try {
FileOutputStream out = new FileOutputStream(file);
IOUtils.copyBinaryTo(new ByteArrayInputStream(content.getContent()), out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
JSONObject jo = JSONObject.create().put("res", "Thank You, I Have The File!");
ctx.writeAndFlush(jo.toString());
ctx.close();
} catch (JSONException e) {
e.printStackTrace();
}
}

完整的代码如下

FileClient & FileClientHandler

 package test;

 import com.fr.general.IOUtils;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import com.fr.stable.core.UUID;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.string.StringEncoder; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; public class FileClient { public FileClient(){ } public void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() { @Override
protected void initChannel(SocketChannel s) throws Exception {
ChannelPipeline p = s.pipeline();
// 传输文本给服务器端
p.addLast(new StringEncoder());
// 二进制文件获取解析
p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(this
.getClass().getClassLoader())));
// 客户端业务代码
p.addLast(new FileClientHandler());
}
});
ChannelFuture future = bootstrap.connect("localhost", 7766).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
} public static void main(String[] args) throws InterruptedException {
new FileClient().start();
} private static class FileClientHandler extends ChannelInboundHandlerAdapter { @Override
public void channelActive(ChannelHandlerContext ctx) {
try {
// 将要获取的pdf路径发送给服务器端
JSONObject jo = JSONObject.create().put("path", "d:\\a.pdf");
ctx.writeAndFlush(jo.toString());
} catch (JSONException e) {
e.printStackTrace();
}
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
PDFContent content = (PDFContent) msg;
// 从服务器端获取的二进制文件存到本地
String fileName = UUID.randomUUID().toString() + ".pdf";
File file = new File("D:\\" + fileName);
try {
FileOutputStream out = new FileOutputStream(file);
IOUtils.copyBinaryTo(new ByteArrayInputStream(content.getContent()), out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
JSONObject jo = JSONObject.create().put("res", "Thank You, I Have The File!");
ctx.writeAndFlush(jo.toString());
ctx.close();
} catch (JSONException e) {
e.printStackTrace();
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
}

FileServer & FileServerHandler

 package test;

 import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler; import java.io.FileInputStream; public class FileServer { private FileServer() {
startServer();
} private void startServer() {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// 解析客户端发送的文本json
pipeline.addLast(new StringDecoder());
// 二进制文件加密传输
pipeline.addLast(new ObjectEncoder());
// 业务逻辑
pipeline.addLast(new FileServerHandler());
}
});
ChannelFuture future = bootstrap.bind("localhost", 7766).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
} } private class FileServerHandler extends ChannelInboundHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 获取到客户端请求, 解析path, 返回二进制文件
JSONObject jo = new JSONObject(msg.toString());
if (StringUtils.isNotEmpty(jo.optString("path"))) {
PDFContent pdf = new PDFContent();
byte[] content = com.fr.general.IOUtils.inputStream2Bytes(new FileInputStream(jo.optString("path")));
pdf.setContent(content);
ctx.writeAndFlush(pdf);
} else {
System.out.println(jo.optString("res"));
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
} public static void main(String[] args){
// 启动Server
new FileServer();
} }

PDFContent

 package test;

 import java.io.Serializable;

 /**
* 文件的封装
*/
public class PDFContent implements Serializable{ private byte[] content; public byte[] getContent() {
return content;
} public void setContent(byte[] content) {
this.content = content;
}
}

Netty之二进制文件传输的更多相关文章

  1. [netty4][netty-transport]netty之nio传输层

    [netty4][netty-transport]netty之nio传输层 nio基本处理逻辑 查看这里 Selector的处理 Selector实例构建 NioEventLoop.openSelec ...

  2. WebService之Axis2(4):二进制文件传输

    在<WebService大讲堂之Axis2(2):复合类型数据的传递>中讲过,如果要传递二进制文件(如图像.音频文件等),可以使用byte[]作为数据类型进行传递,然后客户端使用RPC方式 ...

  3. netty中的传输

    终于在课设的闲时间把netty实战的四五章给解决了 这里来记录一下第四章里面所讲的IO 首先说到IO,我想,必须要先了解阻塞,非阻塞,同步和异步这四个词 看到一个讲的很易懂的例子:https://ww ...

  4. Netty 框架学习 —— 传输

    概述 流经网络的数据总是具有相同的类型:字节,这些字节如何传输主要取决于我们所说的网络传输.用户并不关心传输的细节,只在乎字节是否被可靠地发送和接收 如果使用 Java 网络编程,你会发现,某些时候当 ...

  5. netty的对象传输

    pom <!-- https://mvnrepository.com/artifact/io.netty/netty-all --> <dependency> <grou ...

  6. netty 对象序列化传输示例

    package object.server.impl; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Chann ...

  7. Netty进行文件传输

    本次是利用TCP在客户端发送文件流,服务端就接收流,写入相应的文件. 实验的源文件是一个图片,假设地址是D:\\Koala.jpg,接收保存后的图片为D:\\test.jpg 原理就是将文件读取成by ...

  8. 快来体验快速通道,netty中epoll传输协议详解

    目录 简介 epoll的详细使用 EpollEventLoopGroup EpollEventLoop EpollServerSocketChannel EpollSocketChannel 总结 简 ...

  9. 【Netty】Netty传输

    一.前言 在简单学习了Netty中的组件后,接着学习Netty中数据的传输细节. 二.传输 2.1 传输示例 Netty中的数据传输都是使用的字节类型,下面通过一个实例进行说明,该实例中服务器接受请求 ...

随机推荐

  1. GCC(警告.优化以及调试选项)

    GCC(警告.优化以及调试选项) [介绍] gcc and g++分别是gnu的c & c++编译器   gcc/g++在执行编译工作的时候,总共需要4步   1.预处理,生成.i的文件 预处 ...

  2. Leetcode题解(十一)

    31.Next Permutation 题目 这道题目的意思是给定一个序列,找出其按照字典顺序的下一个顺序,如果给定顺序是字典中的最后一个顺序,其下一个顺序则为字典中的第一个顺序.比如: 1,2,3, ...

  3. Fibonacci again and again(SG函数应用)

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...

  4. zookeeper分布式搭建

    1下载并解压zookeeper安装包 2进入zookeeper配置文件目录,找到zoo_sample.cfg,执行cp zoo_sample.cfg  zoo.cfg 3打开zoo.cfg文件,修改d ...

  5. redhat7 Samba

    1.先安装Samba服务 yum install -y samba samba-client 2.配置文件 vi /etc/samba/smb.conf  --主配置文件 [global]  --全局 ...

  6. Scrum Meeting Alpha - 4

    Scrum Meeting - NewTeam // 地点:新主楼F座二楼 任务反馈 团队成员 完成任务 计划任务 安万贺 确定了API部分的目录结构及包装方式,完成了部分API的包装https:// ...

  7. MyEclipse和Eclipse非常方便的快捷键

    1. ctrl+shift+r:打开资源这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如applic*.xml ...

  8. JavaScript学习笔记(一)——数据类型和变量

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  9. 深度学习之tensorflow (一)

    一.TensorFlow简介 1.TensorFlow定义: tensor  :张量,N维数组 Flow   :  流,基于数据流图的计算 TensorFlow : 张量从图像的一端流动到另一端的计算 ...

  10. Python基础---python中的异常处理

    Python中的异常处理 一.什么是异常处理 python解释器检测到错误,触发异常(也允许程序员自己触发异常) 程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关) ...