netty4.x 传输文件

一:简介

    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

 

转载于:https://www.cnblogs.com/cq-jiang/p/7620425.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值