zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    redis学习(二)-高级特性
    redis学习(一)-基础知识
    设计模式类型
    装饰者设计模式
    udp代理
    docker: unrecognized service
    centos6.x 编译安装zabbix_proxy 2.2.5
    写了一个shell,删除15天以上日志
    tempo 删除团队失败
    github批量删除organization下的private repo
  • 原文地址:https://www.cnblogs.com/cq-jiang/p/7620425.html
Copyright © 2011-2022 走看看