Bootstrap

Java中通过UDP协议传输文件

UDP协议本身并不支持大文件传输,因为UDP协议不保证数据的可靠性和顺序性,而且UDP数据包的大小也有限制。因此,在实现UDP传输大文件时,需要进行以下优化:分割文件、数据传输前协商、确认接收、重传机制。

当传输文件大小小于65535字节时,可以采用下面方式传输,若文件大小超过65535字节时,则见本文的3种方式。

        DatagramSocket datagramSocket = new DatagramSocket();
        // 最大65535字节
        Path path = Paths.get("D:/105721.txt");
        byte[] msg = Files.readAllBytes(path);
        String content = new String(msg, "utf-8");
        byte[] result = new byte[msg.length + 2];
        // 接口信息类型
        byte[] type = {(byte) 0xE0, (byte) 0x02};
        System.arraycopy(type, 0, result, 0, type.length);
        System.arraycopy(msg, 0, result, 2, msg.length);
        DatagramPacket datagramPacket = new DatagramPacket(result, result.length, new InetSocketAddress("127.0.0.1", 50000));
        datagramSocket.send(datagramPacket);
        datagramSocket.close();

1、通过UDP协议传输单个文件

通过控制发送的频率,提高报文的传输的精准性;每包传输的报文大小默认最大为2048字节,若每包传输的报文大于2048字节则需设置相关参数。

        DatagramSocket datagramSocket = new DatagramSocket();
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("D:/105721.txt"));
        byte bytes[] = new byte[2048];
        byte result[] = new byte[2050];
        byte[] type = {(byte) 0xE0, (byte) 0x02};
        byte[] end = "quit".getBytes();
        while (bufferedInputStream.read(bytes,0, bytes.length) != -1){
            // 接口信息类型
            System.arraycopy(type, 0, result, 0, type.length);
            System.arraycopy(bytes, 0, result, 2, bytes.length);
            datagramSocket.send(new DatagramPacket(result,0,result.length,InetAddress.getByName("127.0.0.1"),50000));
            try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }
        System.arraycopy(type, 0, result, 0, type.length);
        System.arraycopy(end, 0, result, 2, end.length);
        datagramSocket.send(new DatagramPacket(result,0,result.length,InetAddress.getByName("127.0.0.1"),50000));

        datagramSocket.close();

2、通过UDP协议传输多个文件

        DatagramSocket datagramSocket = new DatagramSocket();
        File file = new File("D:/aaa");
        String[] fileList = file.list();
        for (String fileName : fileList) {
            String childFilePath = "D:/aaa" + "/" + fileName;
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(childFilePath));
            byte bytes[] = new byte[2000];
            byte[] type = {(byte) 0xE0, (byte) 0x02};
            byte[] name = fileName.getBytes(StandardCharsets.UTF_8);
            byte[] end = "quit".getBytes();
            byte result[] = new byte[type.length + name.length + 2000];
            int i = 0;
            while (bufferedInputStream.read(bytes,0, bytes.length) != -1){
                String s = new String(bytes);
                System.out.println(s + i++);
                System.arraycopy(type, 0, result, 0, type.length);
                System.arraycopy(name, 0, result, type.length, name.length);
                System.arraycopy(bytes, 0, result, type.length + name.length, bytes.length);
                datagramSocket.send(new DatagramPacket(result,0,result.length,InetAddress.getByName("127.0.0.1"),50000));
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.arraycopy(type, 0, result, 0, type.length);
            System.arraycopy(end, 0, result, type.length, end.length);
            datagramSocket.send(new DatagramPacket(result,0,result.length,InetAddress.getByName("127.0.0.1"),50000));
        }
        datagramSocket.close();

3、通过UDP协议传输压缩包中的指定文件

		DatagramSocket datagramSocket = new DatagramSocket();
		// 读取指定压缩文件中的文件
        String filename = "D:/aaa.zip";
        String fileToRead = "111612.txt";
        File inputFile = new File(filename);
        ZipFile zipFile = new ZipFile(inputFile);
        ZipEntry entry = zipFile.getEntry(fileToRead);
        InputStream inputStream = zipFile.getInputStream(entry);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
        byte bytes[] = new byte[2000];
        byte[] type = {(byte) 0xE0, (byte) 0x02};
        byte[] name = fileToRead.getBytes(StandardCharsets.UTF_8);
        byte[] end = "quit".getBytes();
        byte result[] = new byte[type.length + name.length + 2000];
        int i = 0;
        while (bufferedInputStream.read(bytes,0, bytes.length) != -1){
            String s = new String(bytes);
            System.out.println(s + i++);
            System.arraycopy(type, 0, result, 0, type.length);
            System.arraycopy(name, 0, result, type.length, name.length);
            System.arraycopy(bytes, 0, result, type.length + name.length, bytes.length);
            datagramSocket.send(new DatagramPacket(result,0,result.length,InetAddress.getByName("127.0.0.1"),50000));
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.arraycopy(type, 0, result, 0, type.length);
        System.arraycopy(end, 0, result, type.length, end.length);
        datagramSocket.send(new DatagramPacket(result,0,result.length,InetAddress.getByName("127.0.0.1"),50000));
        datagramSocket.close();

注:以上3种方式只做参考,具体还需根据场景修改,且传输完成的文件会比原文件在文档的最后多n行内容,因为设定的每包传输的报文大小为2000字节。

;