一:简介
netty传输文件的例子并不多,当前的项目刚才需要使用netty,所以就记录一下使用方法,使用netty传输文件,首先需要启动一个服务端,等待服务端请求监听,然后传输文件的时候,启动一个客户端线程来传输文件。
二:启动一个服务端等待监听
1):引入netty版本号
<dependency> ???????????<groupId>io.netty</groupId> ???????????<artifactId>netty-all</artifactId> ???????????<version>4.1.15.Final</version> ???????</dependency>
2):启动一个服务端
//声明两个多线程事件循环器EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();//声明nio服务启动类ServerBootstrap serverBootstrap = new ServerBootstrap (); b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChannelInitializer<Channel>() { ???????????????@Override ???????????????protected void initChannel(Channel ch) throws Exception { ???????????????????System.out.println("有客户端连接上来:"+ch.localAddress().toString()); ???????????????????ch.pipeline().addLast(new ObjectEncoder()); ???????????????????ch.pipeline().addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingConcurrentResolver(null))); // 最大长度 ???????????????????ch.pipeline().addLast(new FileUploadServerHandler()); ???????????????} ???????????}); ???????????ChannelFuture f = b.bind(port).sync();//邦定端口并启动 ???????????System.out.println("file server 等待连接:"); ???????????f.channel().closeFuture().sync();
3):接收文件的handler extends ChannelInboundHandlerAdapter,在channelRead方法中获取文件
//自定义的一个对像,保存文件相关的属性FileUploadFile ef = (FileUploadFile) msg; ???????????byte[] bytes = ef.getBytes(); ???????????byteRead = ef.getEndPos(); ???????????String md5 = ef.getFile_md5();//文件名 ????????//读文件的相关代码String path = file_dir + File.separator + md5; ???????????File file = new File(path); ???????????RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); ???????????randomAccessFile.seek(start); ???????????randomAccessFile.write(bytes); ???????????start = start + byteRead; ???????????System.out.println("path:"+path+","+byteRead); ???????????if (byteRead > 0) { ???????????????ctx.writeAndFlush(start); ???????????????randomAccessFile.close(); ???????????????if(byteRead!=1024 * 10){//测试每次读取10k,当文件大小不是10k时,默认文件读完, 这里可以不用调用channelInactive() ???????????????????Thread.sleep(1000); ???????????????????channelInactive(ctx); ???????????????} ???????????} else { ???????????????//System.out.println("文件接收完成"); ???????????????//ctx.flush(); ????????????????ctx.close(); ???????????} ???????????????????} ???????
服务端的代码大致就是这些,我们来看客户端的代码。
4:) 初始化客户端
//客户端只创建一个事件循环处理器EventLoopGroup group = new NioEventLoopGroup();try { ???????????Bootstrap b = new Bootstrap();
//注意这里和服务端的区别,服务端:NioServerSocketChannel,客户端:NioSocketChannel
b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline() .addLast(
new ObjectDecoder( ClassResolvers .weakCachingConcurrentResolver(null)));
ch.pipeline() .addLast( new FileUploadClientHandler( fileUploadFile)); } });
ChannelFuture f = b.connect(host, port).sync(); //连接服务端
f.channel().closeFuture().sync();//关闭
5:)上传文件的handler同样继承为 ChannelInboundHandlerAdapter
在channelInactive方法将文件相关信息,如:文件名,文件长度等封装一个对像,输出至服务端
FileUploadFile uploadFile = new FileUploadFile();File file = new File("d:/source.rar");String fileMd5 = file.getName();// 文件名uploadFile.setFile(file);uploadFile.setFile_md5(fileMd5);
在channelRead方法来读取和上传文件流
randomAccessFile = new RandomAccessFile( ???????????????????????fileUploadFile.getFile(), "r");randomAccessFile.seek(start);fileUploadFile.setEndPos(byteRead);fileUploadFile.setBytes(bytes); ???try { ???????ctx.writeAndFlush(fileUploadFile); ???} catch (Exception e) { ???????e.printStackTrace(); ???}
主要的代码就是这些,demo下载地址:github
netty4.x 传输文件
原文地址:http://www.cnblogs.com/cq-jiang/p/7620425.html