Java 客户端、服务端NIO大文件传输

1 篇文章 0 订阅
1 篇文章 0 订阅

一、需求

公司电脑不让使用U盘,又不想通过公司聊天软件传输,怕被监控。但是通过QQ、微信传输文件对文件大小又有限制。基于种种原因,自己简单写了个服务端、客户端进行文件传输,大文件最好在局域网内进行数据传输。

二、pom依赖

        
         <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>

三、定义服务端

服务端用于接收文件

@Slf4j
public class FileServer {

    /**
     * 设置服务端端口
     */
    public static final int PORT = 9999;
    /**
     * 指定保存文件地址 例如要把公司文件A,传输到家里电脑上,存为B文件,这里就是B文件的地址
     */
    public static final String PATH = "/Users/admin/Downloads/yinyue31.zip";

    public static void main(String[] args) {
        FileChannel fileChannel = null;
        SocketChannel socketChannel = null;
        try {
            // 1. 创建并配置 服务器套接字通道 ServerSocketChannel
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            //设置端口
            serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
            // 注意这里使用阻塞模式, 不调用该代码
            // serverSocketChannel.configureBlocking(false);
            // 2. 获取文件通道
            fileChannel = new FileOutputStream(PATH).getChannel();
            log.info("服务端启动完毕******等待接收文件");
            // 3. 阻塞等待
            socketChannel = serverSocketChannel.accept();
            log.info("服务端开始接收文件******");
            long startTime = System.currentTimeMillis();
            // 4. 零拷贝核心操作
            fileChannel.transferFrom(socketChannel, 0, Long.MAX_VALUE);
            log.info("服务端接收文件结束,耗时{}ms", System.currentTimeMillis() - startTime);
        } catch (IOException e) {
            log.error("服务端接收异常{}", e);
        } finally {
            // 5. 释放资源
            if (null != socketChannel) {
                try {
                    socketChannel.close();
                } catch (IOException e) {
                    log.error("服务端关闭流socketChannel异常{}", e);
                }
            }
            if (null != fileChannel) {
                try {
                    fileChannel.close();
                } catch (IOException e) {
                    log.error("服务端关闭流socketChannel异常{}", e);
                }
            }
        }
    }
}

四、定义客户端

客户端用于发送文件

@Slf4j
public class FileClient {

    /**
     * 设置需要访问的服务端IP
     */
    public static final String IP = "127.0.0.1";

    /**
     * 设置需要访问的服务端端口
     */
    public static final int PORT = 9999;
    /**
     * 指定读取的文件地址(要被传输的文件) 例如要把文件A传输到家里电脑上,这里就是A文件的地址
     */
    public static final String PATH = "/Users/admin/Downloads/ioa.zip";

    public static void main(String[] args) {
        FileChannel fileChannel = null;
        SocketChannel socketChannel = null;
        try {
            // 1. 创建并配置 服务器套接字通道 ServerSocketChannel
            socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress(IP, PORT));
            //socketChannel.configureBlocking(false);
            // 2. 从文件输入流中获取文件通道 ( FileChannel )
            fileChannel = new FileInputStream(PATH).getChannel();
            long startTime = System.currentTimeMillis();
            // 3. 零拷贝传输数据, 注意记录每次拷贝的起始位置
            long transferLen;
            long totalCount = 0;
            log.info("文件开始传输******");
            // 使用零拷贝将文件数据传到服务器, 循环终止条件是传输结果小于等于 0
            while ((transferLen = fileChannel.transferTo(totalCount, Long.MAX_VALUE, socketChannel)) > 0) {
                totalCount += transferLen;
                log.info("文件大小:{}", transferLen);
            }
            log.info("文件传输完毕, 用时:{}ms", System.currentTimeMillis() - startTime);
        } catch (IOException e) {
            log.error("客户端传输异常{}", e);
        } finally {
            // 5. 释放资源
            if (null != socketChannel) {
                try {
                    socketChannel.close();
                } catch (IOException e) {
                    log.error("客户端关闭流socketChannel异常{}", e);
                }
            }
            if (null != fileChannel) {
                try {
                    fileChannel.close();
                } catch (IOException e) {
                    log.error("客户端关闭流fileChannel异常{}", e);
                }
            }
        }
    }
}

五、修改重要参数

FileClient

这个类是客户端,要把文件传输到服务端。公司电脑启动这个类。

1、设置需要访问的服务端IP public static final String IP = “127.0.0.1”;
2、设置需要访问的服务端端口 public static final int PORT = 9999;
3、指定读取的文件地址(要被传输的文件) 例如要把文件A传输到家里电脑上,这里就是A文件的地址 public static final String PATH = “/Users/admin/Downloads/ioa.zip”;

FileServer

这个类是服务端,要接收文件的服务。家里电脑启动这个类。

1、设置服务端端口 public static final int PORT = 9999;
2、指定保存文件地址 例如要把公司文件A,传输到家里电脑上,存为B文件,这里就是B文件的地址 public static final String PATH = “/Users/admin/Downloads/yinyue31.zip”;

六、测试

需要在一个局域网下,台式机可能不方便。最好有一台电脑是笔记本。
1、公司电脑和家里电脑都用idea打开这个工程
2、家里电脑运行FileServer类中的main方法
3、公司电脑运行FileClient类中的main方法

七、完整代码

GitHub地址:https://github.com/9925dev/netty-transmission-file

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值