标签:log ted none void rup hid empty lap exce
客户端发起一个文本请求给服务器端, 服务器端解析里面文本, 返回文件给客户端, 客户端解析文件
因为示例文件比较小, 所以没有做分段传输, 而是直接一次性把整个文件byte[]都发给客户端了.
如果需要传输大文件, 则需要做粘包拆包, 参考另外一篇博文 Netty之粘包分包
需要三个ChannelPipeline
1 // 解析客户端发送的文本json 2 pipeline.addLast(new StringDecoder()); 3 // 二进制文件加密传输 4 pipeline.addLast(new ObjectEncoder()); 5 // 业务逻辑 6 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
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业务逻辑
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
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
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
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 }
标签:log ted none void rup hid empty lap exce
原文地址:http://www.cnblogs.com/xdecode/p/7978147.html