前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty之二进制文件传输

Netty之二进制文件传输

作者头像
用户1216491
发布2018-01-24 16:06:31
2.3K0
发布2018-01-24 16:06:31
举报
文章被收录于专栏:xdecodexdecode

传输会话简要

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

服务器端

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

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

需要三个ChannelPipeline

代码语言:javascript
复制
1                             // 解析客户端发送的文本json
2                             pipeline.addLast(new StringDecoder());
3                             // 二进制文件加密传输
4                             pipeline.addLast(new ObjectEncoder());
5                             // 业务逻辑
6                             pipeline.addLast(new FileServerHandler());

FileServerHandler业务逻辑

代码语言:javascript
复制
            // 获取到客户端请求, 解析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

代码语言:javascript
复制
1                             // 传输文本给服务器端
2                             p.addLast(new StringEncoder());
3                             // 二进制文件获取解析
4                             p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(this
5                                     .getClass().getClassLoader())));
6                             // 客户端业务代码
7                             p.addLast(new FileClientHandler());

FileClientHandler业务逻辑

代码语言:javascript
复制
 1         @Override
 2         public void channelActive(ChannelHandlerContext ctx) {
 3             try {
 4                 // 将要获取的pdf路径发送给服务器端
 5                 JSONObject jo = JSONObject.create().put("path", "d:\\a.pdf");
 6                 ctx.writeAndFlush(jo.toString());
 7             } catch (JSONException e) {
 8                 e.printStackTrace();
 9             }
10         }
11 
12         @Override
13         public void channelRead(ChannelHandlerContext ctx, Object msg) {
14             PDFContent content = (PDFContent) msg;
15             // 从服务器端获取的二进制文件存到本地
16             String fileName = UUID.randomUUID().toString() + ".pdf";
17             File file = new File("D:\\" + fileName);
18             try {
19                 FileOutputStream out = new FileOutputStream(file);
20                 IOUtils.copyBinaryTo(new ByteArrayInputStream(content.getContent()), out);
21                 out.close();
22             } catch (FileNotFoundException e) {
23                 e.printStackTrace();
24             } catch (IOException e) {
25                 e.printStackTrace();
26             }
27             try {
28                 JSONObject jo = JSONObject.create().put("res", "Thank You, I Have The File!");
29                 ctx.writeAndFlush(jo.toString());
30                 ctx.close();
31             } catch (JSONException e) {
32                 e.printStackTrace();
33             }
34         }

完整的代码如下

FileClient & FileClientHandler

代码语言:javascript
复制
  1 package test;
  2 
  3 import com.fr.general.IOUtils;
  4 import com.fr.json.JSONException;
  5 import com.fr.json.JSONObject;
  6 import com.fr.stable.core.UUID;
  7 import io.netty.bootstrap.Bootstrap;
  8 import io.netty.channel.ChannelFuture;
  9 import io.netty.channel.ChannelHandlerContext;
 10 import io.netty.channel.ChannelInboundHandlerAdapter;
 11 import io.netty.channel.ChannelInitializer;
 12 import io.netty.channel.ChannelPipeline;
 13 import io.netty.channel.EventLoopGroup;
 14 import io.netty.channel.nio.NioEventLoopGroup;
 15 import io.netty.channel.socket.SocketChannel;
 16 import io.netty.channel.socket.nio.NioSocketChannel;
 17 import io.netty.handler.codec.serialization.ClassResolvers;
 18 import io.netty.handler.codec.serialization.ObjectDecoder;
 19 import io.netty.handler.codec.string.StringEncoder;
 20 
 21 import java.io.ByteArrayInputStream;
 22 import java.io.File;
 23 import java.io.FileNotFoundException;
 24 import java.io.FileOutputStream;
 25 import java.io.IOException;
 26 
 27 public class FileClient {
 28 
 29     public FileClient(){
 30 
 31     }
 32 
 33     public void start() {
 34         EventLoopGroup group = new NioEventLoopGroup();
 35         try {
 36             Bootstrap bootstrap = new Bootstrap();
 37             bootstrap.group(group)
 38                     .channel(NioSocketChannel.class)
 39                     .handler(new ChannelInitializer<SocketChannel>() {
 40 
 41                         @Override
 42                         protected void initChannel(SocketChannel s) throws Exception {
 43                             ChannelPipeline p = s.pipeline();
 44                             // 传输文本给服务器端
 45                             p.addLast(new StringEncoder());
 46                             // 二进制文件获取解析
 47                             p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(this
 48                                     .getClass().getClassLoader())));
 49                             // 客户端业务代码
 50                             p.addLast(new FileClientHandler());
 51                         }
 52                     });
 53             ChannelFuture future = bootstrap.connect("localhost", 7766).sync();
 54             future.channel().closeFuture().sync();
 55         } catch (InterruptedException e) {
 56             e.printStackTrace();
 57         } finally {
 58             group.shutdownGracefully();
 59         }
 60     }
 61 
 62     public static void main(String[] args) throws InterruptedException {
 63         new FileClient().start();
 64     }
 65 
 66     private static class FileClientHandler extends ChannelInboundHandlerAdapter {
 67 
 68 
 69         @Override
 70         public void channelActive(ChannelHandlerContext ctx) {
 71             try {
 72                 // 将要获取的pdf路径发送给服务器端
 73                 JSONObject jo = JSONObject.create().put("path", "d:\\a.pdf");
 74                 ctx.writeAndFlush(jo.toString());
 75             } catch (JSONException e) {
 76                 e.printStackTrace();
 77             }
 78         }
 79 
 80         @Override
 81         public void channelRead(ChannelHandlerContext ctx, Object msg) {
 82             PDFContent content = (PDFContent) msg;
 83             // 从服务器端获取的二进制文件存到本地
 84             String fileName = UUID.randomUUID().toString() + ".pdf";
 85             File file = new File("D:\\" + fileName);
 86             try {
 87                 FileOutputStream out = new FileOutputStream(file);
 88                 IOUtils.copyBinaryTo(new ByteArrayInputStream(content.getContent()), out);
 89                 out.close();
 90             } catch (FileNotFoundException e) {
 91                 e.printStackTrace();
 92             } catch (IOException e) {
 93                 e.printStackTrace();
 94             }
 95             try {
 96                 JSONObject jo = JSONObject.create().put("res", "Thank You, I Have The File!");
 97                 ctx.writeAndFlush(jo.toString());
 98                 ctx.close();
 99             } catch (JSONException e) {
100                 e.printStackTrace();
101             }
102         }
103 
104         @Override
105         public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
106             cause.printStackTrace();
107             ctx.close();
108         }
109     }
110 }

FileServer & FileServerHandler

代码语言:javascript
复制
 1 package test;
 2 
 3 import com.fr.json.JSONObject;
 4 import com.fr.stable.StringUtils;
 5 import io.netty.bootstrap.ServerBootstrap;
 6 import io.netty.channel.ChannelFuture;
 7 import io.netty.channel.ChannelHandlerContext;
 8 import io.netty.channel.ChannelInboundHandlerAdapter;
 9 import io.netty.channel.ChannelInitializer;
10 import io.netty.channel.ChannelOption;
11 import io.netty.channel.ChannelPipeline;
12 import io.netty.channel.EventLoopGroup;
13 import io.netty.channel.nio.NioEventLoopGroup;
14 import io.netty.channel.socket.SocketChannel;
15 import io.netty.channel.socket.nio.NioServerSocketChannel;
16 import io.netty.handler.codec.serialization.ObjectEncoder;
17 import io.netty.handler.codec.string.StringDecoder;
18 import io.netty.handler.logging.LogLevel;
19 import io.netty.handler.logging.LoggingHandler;
20 
21 import java.io.FileInputStream;
22 
23 public class FileServer {
24 
25     private FileServer() {
26         startServer();
27     }
28 
29     private void startServer() {
30         EventLoopGroup bossGroup = new NioEventLoopGroup(1);
31         EventLoopGroup workerGroup = new NioEventLoopGroup();
32         try{
33             ServerBootstrap bootstrap = new ServerBootstrap();
34             bootstrap.group(bossGroup, workerGroup)
35                     .channel(NioServerSocketChannel.class)
36                     .option(ChannelOption.SO_BACKLOG, 100)
37                     .handler(new LoggingHandler(LogLevel.INFO))
38                     .childHandler(new ChannelInitializer<SocketChannel>() {
39                         @Override
40                         protected void initChannel(SocketChannel ch) throws Exception {
41                             ChannelPipeline pipeline = ch.pipeline();
42                             // 解析客户端发送的文本json
43                             pipeline.addLast(new StringDecoder());
44                             // 二进制文件加密传输
45                             pipeline.addLast(new ObjectEncoder());
46                             // 业务逻辑
47                             pipeline.addLast(new FileServerHandler());
48                         }
49                     });
50             ChannelFuture future = bootstrap.bind("localhost", 7766).sync();
51             future.channel().closeFuture().sync();
52         } catch (InterruptedException e) {
53             e.printStackTrace();
54         } finally {
55             bossGroup.shutdownGracefully();
56             workerGroup.shutdownGracefully();
57         }
58 
59     }
60 
61     private class FileServerHandler extends ChannelInboundHandlerAdapter {
62 
63         @Override
64         public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
65             // 获取到客户端请求, 解析path, 返回二进制文件
66             JSONObject jo = new JSONObject(msg.toString());
67             if (StringUtils.isNotEmpty(jo.optString("path"))) {
68                 PDFContent pdf = new PDFContent();
69                 byte[] content = com.fr.general.IOUtils.inputStream2Bytes(new FileInputStream(jo.optString("path")));
70                 pdf.setContent(content);
71                 ctx.writeAndFlush(pdf);
72             } else {
73                 System.out.println(jo.optString("res"));
74             }
75         }
76 
77         @Override
78         public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
79             cause.printStackTrace();
80             ctx.close();
81         }
82     }
83 
84     public static void main(String[] args){
85         // 启动Server
86         new FileServer();
87     }
88 
89 
90 }

PDFContent

代码语言:javascript
复制
 1 package test;
 2 
 3 import java.io.Serializable;
 4 
 5 /**
 6  * 文件的封装
 7  */
 8 public class PDFContent implements Serializable{
 9 
10     private byte[] content;
11 
12     public byte[] getContent() {
13         return content;
14     }
15 
16     public void setContent(byte[] content) {
17         this.content = content;
18     }
19 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 传输会话简要
  • 服务器端
  • 客户端
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档