UDP(不可靠)链接(文件传输)

发送方

import java.io.*;
import java.net.*;
import java.util.Arrays;
import java.util.Random;
import java.util.logging.Logger;


public class SendFile{
    private Logger log = Logger.getLogger("SendFile");
    /**
     * 接收方地址
     */
    private String address = "127.0.0.1";
    /**
     * 接收方端口
     */
    private String port = "10086";
    /**
     * 发送的文件地址
     */
    private String fileName = null;
    /**
     * 发送文件的缓冲区大小
     */
    private static final int SEND_SIZE = 1024;

    /**
     * 文件结束符长度
     */
    private static int FILE_END_SIZE = 100;

    /**
     * 入口函数
     * @param args args[0]: 文件位置.  args[1]: ip 地址(默认:127.0.0.1)。 args[2]:端口号(默认:10086)
     */
    public static void main(String[] args) {


        if(args.length <= 0) {
            System.out.println("需要参数 文件位置。");
            System.exit(0);
        }
        SendFile sendFile = new SendFile();
        sendFile.fileName = args[0];
        if(args.length == 1){
            sendFile.log.warning("使用默认 ip 地址");
        }else{
            sendFile.address = args[1];
            sendFile.log.info("使用 IP 地址:"+args[1]);
        }
        if(args.length > 2)sendFile.port = args[2];
        sendFile.log.info("使用端口号:"+sendFile.port);
        sendFile.start();
    }
    public SendFile(String address){
        this.address = address;
    }
    public SendFile(String address,String fileName){
        this.address = address;
        this.fileName = fileName;
    }
    public SendFile(String address,String port,String fileName){
        this.address = address;
        this.port = port;
        this.fileName = fileName;
    }
    public SendFile(){}
    public void start(){
        if(fileName==null||fileName.equals("")){
            log.severe("文件名不能为空");
        }
        if(address==null||address.equals("")){
            log.severe("ip 不能为空");
        }

        File file = new File(fileName);
        FileInputStream fileInputStream = null;
        //创建数据缓冲区
        byte [] sendBytes = new byte[SEND_SIZE];
        int len = SEND_SIZE;
        //建立UDP连接
        DatagramSocket datagramSocket = null;
        DatagramPacket p = null;

        try {
            long st = System.currentTimeMillis();
            fileInputStream = new FileInputStream(file);
            datagramSocket = new DatagramSocket();
            byte[] fileEndBytes = buildFileEnd(FILE_END_SIZE,getLastFileName());
            //System.out.println(getLastFileName());

            p = new DatagramPacket(fileEndBytes,FILE_END_SIZE,InetAddress.getByName(address),Integer.parseInt(port));
            //发送文件结束符
            log.info("发送文件结束符,长度:"+FILE_END_SIZE);
            datagramSocket.send(p);
            log.info("发送文件结束符成功");
            //发送数据
            while((len = fileInputStream.read(sendBytes,0,len)) != -1){

                p.setData(sendBytes,0,len);
                datagramSocket.send(p);
                log.info("发送数据包成功,长度:"+len+" byte");
            }
            //再次发送文件结束符
            log.info("再次发送文件结束符,长度:"+FILE_END_SIZE);
            p.setData(fileEndBytes,0,FILE_END_SIZE);
            datagramSocket.send(p);
            log.info("文件发送完毕,用时:"+((System.currentTimeMillis()-st)/1024)+" s");

        } catch (UnknownHostException e) {
            log.severe("ip 地址创建失败,错误信息:"+e.getMessage());
        } catch (FileNotFoundException e) {
            log.severe("文件打开失败,错误信息:"+e.getMessage());
        } catch (IOException e) {
            log.severe("文件信息读取失败,错误信息:"+e.getMessage());
        } finally {
            try {
                if(fileInputStream!=null)fileInputStream.close();
                if(datagramSocket!=null)datagramSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /** 创建文件结束符
     * @param length 长度
     * @param nameFile 加入文件名称
     * @return
     */
    private byte[] buildFileEnd(int length,String nameFile){
        if(length>SEND_SIZE)length = SEND_SIZE;
        byte[] bytes = new byte[length];
        Random random = new Random(System.currentTimeMillis());
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) random.nextInt(120+1);
        }
        byte[] bytes1 = nameFile.getBytes();
        bytes[0] = (byte) Math.min(FILE_END_SIZE,bytes1.length-1);
        for(int i=1;i<FILE_END_SIZE&&i<bytes1.length+1;i++){
            bytes[i] = bytes1[i-1];
        }
        return bytes;
    }

    /**
     * 获取文件名称
     * @return
     */
    private String getLastFileName(){
        int i = fileName.lastIndexOf("\\");
        int j = fileName.lastIndexOf("/");
        if(i>=0&&i<fileName.length())return fileName.substring(i+1,fileName.length());
        else if(j>=0&&j<fileName.length())return fileName.substring(j+1,fileName.length());
        log.severe("获取文件名失败");
        return null;
    }


    public void send(String fileName){
        this.fileName = fileName;
        this.start();
    }


}

接收方

import java.io.*;
import java.net.*;
import java.util.Arrays;
import java.util.Random;
import java.util.logging.Logger;


public class  ReceiveFile{
    private static final Logger log = Logger.getLogger("ReceiveFile");

    /**
     * 接收的端口号
     */
    private String port = "10086";

    /**
     * 接收的文件地址
     */
    private String fileName = null;
    /**
     * 接收文件的缓冲区大小
     */
    private static final int SEND_SIZE = 1024;

    /**
     * 文件接收结束符
     */
    private byte[] FILE_END = null;
    /**
     * 入口函数
     * @param args args[0]: 文件路径。 args[1]:端口号(默认:10086)
     */
    public static void main(String[] args) {
        if(args.length <= 0) {
            System.out.println("需要参数 文件保存路径。");
            System.exit(0);
        }
        ReceiveFile receiveFile = new ReceiveFile(args[0]);

        if(args.length >= 2)receiveFile.port = args[2];
        receiveFile.log.info("使用端口号:"+receiveFile.port);
        receiveFile.start();
    }

    public ReceiveFile(String fileName) {
        this.fileName = fileName;
    }
    public ReceiveFile() {}

    public ReceiveFile(String port, String fileName) {
        this.port = port;
        this.fileName = fileName;
    }

    public void start(){
        if(fileName==null||fileName.equals("")){
            log.severe("文件名不能为空");
        }
        File file = new File(fileName);
        if(file.mkdirs())log.warning("系统路径不存在,创建系统指定路径。");

        FileOutputStream fileOutputStream = null;

        //创建数据缓冲区
        byte [] receiveBytes = new byte[SEND_SIZE];
        //建立UDP连接
        DatagramSocket datagramSocket = null;
        DatagramPacket p = null;

        try {
            long st = System.currentTimeMillis();

            datagramSocket = new DatagramSocket(Integer.parseInt(port));
            p = new DatagramPacket(receiveBytes,SEND_SIZE);
            while(true){
                if(FILE_END==null)log.info("接收文件结束符");
                //获取实际接收的数据缓冲区长度
                datagramSocket.receive(p);
                int length = p.getLength();
                if(FILE_END==null){ //第一次发送的为文件结束标志

                    log.info("接收文件结束符成功,长度:"+length);
                    FILE_END = Arrays.copyOf(receiveBytes, length);
                    //接受文件名
                    if(fileName.charAt(fileName.length()-1)!='\\'&&fileName.charAt(fileName.length()-1)!='/')fileName+="\\";
                    fileName = fileName + getfileName(receiveBytes,length);
                    //创建文件
                    file = new File(fileName);
                    if(!file.exists())file.createNewFile();
                    fileOutputStream = new FileOutputStream(file);
                    log.info("创建文件"+fileName+"成功");
                }else{

                    if(isFileEnd(receiveBytes,length)){ //是否传输完毕
                        break;
                    }
                    //文件写入
                    fileOutputStream.write(receiveBytes,0,length);
                    log.info("接受数据包,长度:"+length);
                }

                //重新设置缓冲区长度
                p.setLength(SEND_SIZE);

            }

            log.info("文件接收完毕,用时:"+((System.currentTimeMillis()-st)/1000)+" s");
        }catch (SocketException  e){
            log.severe("UDP 链接初始化失败,错误信息:"+e.getMessage());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            log.severe("文件创建失败,请手动创建。错误信息;"+e.getMessage());
        } finally {
            if(fileOutputStream!=null) {
                try {
                    fileOutputStream.close();
                    if(datagramSocket!=null)datagramSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 根据文件结束符获取文件名称
     * @param receiveBytes
     * @param length
     * @return
     */
    private String getfileName(byte[] receiveBytes, int length) {
        int len = receiveBytes[0];
        return new String(receiveBytes, 1, Math.min(len+1,length-1));
    }

    /**
     * 判断文件是否传输完毕
     * @param bytes
     * @return
     */
    private boolean isFileEnd(byte[] bytes,int length){
        if(bytes==null || length!= FILE_END.length)return false;
        for(int i=0 ; i<FILE_END.length ; i++){
            if(FILE_END[i]!=bytes[i])return false;
        }
        return true;
    }
    public void receive(String fileName){
        this.fileName = fileName;
        start();
    }
}




全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务