netty 文件传输
FileServer
package com.zhaowb.netty.ch13_1; 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; import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; import java.io.File; public class FileServer { public void run(int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 100) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( new StringEncoder(CharsetUtil.UTF_8),// 将文件内容编码为字符串 // 这2个解码器一起使用就是文本换行解码器 new LineBasedFrameDecoder(1024),// 根据回车换行符对数据包进行解码 new StringDecoder(CharsetUtil.UTF_8),// 将数据包解码成字符串, new FileServerHandler() ); } }); ChannelFuture f = b.bind(port).sync(); System.out.println("Start file server at port : " + port); f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception{ int port = 8080; new FileServer().run(port); } }
FileServerHandler
package com.zhaowb.netty.ch13_1; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.DefaultFileRegion; import io.netty.channel.FileRegion; import io.netty.channel.SimpleChannelInboundHandler; import java.io.File; import java.io.RandomAccessFile; import java.sql.SQLOutput; public class FileServerHandler extends SimpleChannelInboundHandler<String> { private static final String CR = System.getProperty("line.separator"); @Override protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception { File file = new File(msg); // 校验文件的合法性,不存在构造异常消息返回。如果存在使用RandomAccessFile 以只读的方式打开文件,然后使用netty的 // DefaultFileRegion 进行文件传输, // FileChannel file, 文件通道,用于对文件进行读写操作 // long position,文件操作的指针位置,读取或写入的起始点 // long count,操作的总字符数 if (file.exists()){ if (!file.isFile()){ ctx.writeAndFlush("Not a file " + msg); return; } ctx.write(file +" " + file.length() + CR); RandomAccessFile randomAccessFile = new RandomAccessFile(msg,"r"); FileRegion region = new DefaultFileRegion(randomAccessFile.getChannel(),0,randomAccessFile.length()); ctx.write(region); ctx.writeAndFlush(CR); // 写入换行符,告诉CMD控制台,文件传输结束。 randomAccessFile.close(); }else { ctx.writeAndFlush("File not found " + file + CR); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("连接成功!"); } }
启动FileServer 之后再CMD控制台 输入 telnet localhost 8080
然后输入文件的绝对路径比如 D:\hello.txt ,在操作时,出现了中文乱码的问题,应该是Windows的原因。