单工通信:利用剪切板从本地传送文件到服务器端

一、发送方代码:

import java.awt.*;
import java.awt.datatransfer.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Base64;

public class SendData {
    /**
     *  数据发送间隔时间,单位:毫秒,默认:1000毫秒,
     *  取决于 1.需要等待剪切板被读取,2.间隔在500毫秒以下,可能会被系统禁止读写
     */
    private int delay=2000;//发送延迟
    private int once=600000;//每次发送的数据量  默认:60万字节,取决于双方网络带宽,以及系统剪切板容量
    private int downtime=10;//准备倒计时,单位:秒,默认:10秒
    private String filename;//发送的文件名
    private Clipboard cb ;//剪切板
    /**
     * @param filename 文件名
     */
    public SendData(String filename){
        this.filename=filename;
    }

    public void start() throws IOException {
        /**
         * 开始倒计时
         */
        System.out.println("倒计时"+downtime+"秒开始");
        while (downtime> 0) {
            System.out.println((downtime--)+"秒");
            delay(1000);
        }
        /**
         * 初始化编码器,文件,和文件流
         */
        Base64.Encoder en = Base64.getEncoder();
        cb=Toolkit.getDefaultToolkit().getSystemClipboard();
        File file=new File(filename);
        FileInputStream fi = new FileInputStream(file);
        /**
         * 发送文件名
         */
        int sign = 1;//数据包标记
        setClipboardText(sign + "@" +file.getName());
        /**
         * 开始发送数据
         */
        long file_len=file.length();
        long count = 0;//记录已发送长度
        byte[] bytes = new byte[once];
        int len=0;
        while ((len=fi.read(bytes))>0){
            /**
             * 发送延迟
             */
            delay(delay);
            /**
             * 将读到的字节转换为编码
             */
            String temp_str="";
            sign++;
            count+=len;
            if(len==once){
                /*****************数据长度=字节数组最大容量,表示还没传送结束*********************/
                temp_str=en.encodeToString(bytes);
                System.out.println(sign+":已发送"+(count*100/file_len)+"%");
            }else{
                /*********************数据未填满字节数组,表示传送结束**************************/
                byte[] temp_bytes=new byte[len];
                System.arraycopy(bytes,0,temp_bytes,0,len);
                temp_str=en.encodeToString(temp_bytes);
                System.out.println(sign+":已发送100%");
            }
            /**
             * 写入剪切板
             */
            System.out.println("长度="+temp_str.length());
            setClipboardText(sign + "@" +temp_str);
        }
        delay(delay);
        setClipboardText("-1@");//发送结束标记
        fi.close();
        System.out.println("发送完成");
        delay(delay);
        setClipboardText("");
        System.out.println("已清空剪切板内容");
    }

    public void setClipboardText(String text){
        Transferable tf = new StringSelection(text);
        cb.setContents(tf, null);
    }

    public void delay(int time){
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public int getOnce() {
        return once;
    }

    public SendData setOnce(int once) {
        this.once = once;
        return this;
    }

    public int getDowntime() {
        return downtime;
    }

    public SendData setDowntime(int downtime) {
        this.downtime = downtime;
        return this;
    }

    public int getDelay() {
        return delay;
    }

    public SendData setDelay(int delay) {
        this.delay = delay;
        return this;
    }

    public String getFilename() {
        return filename;
    }

    public SendData setFilename(String filename) {
        this.filename = filename;
        return this;
    }
}

二、接收方:

import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.*;
import java.util.Base64;

public class ReceiveData {
    private String dir_out="D:/dir_out/"; //默认输出路径
    private String file_target;  //保存文件名,默认使用接收来的文件名
    private int read_time=1000;   //读取延迟
    private int time_out=15000;  //最大等待时间(超时时间)
    private  Clipboard cb ;//剪切板

    public ReceiveData(){}
    /**
     *
     * @param file_target 自定义接收的文件名
     */
    public ReceiveData(String file_target){
        this.file_target=file_target;
    }
    /**
     *
     * @param dir_out      自定义接收路径
     * @param file_target   自定义接收的文件名
     */
    public ReceiveData(String dir_out,String file_target){
        this.dir_out=dir_out;
        this.file_target=file_target;
    }
    public void start() throws IOException, UnsupportedFlavorException {
        /**
         * 初始化操作
         */
        int sign=0; //数据标记
        float count_time=0;//累计等待时间
        Base64.Decoder decoder=Base64.getDecoder();
        cb= Toolkit.getDefaultToolkit().getSystemClipboard();
        /**
         * 创建输出路径及文件
         */
        createDir(dir_out);
        while (sign<1){
            delay(read_time);
            String text=getClipboardText();
            int temp_sign=0;
            int p=text.indexOf("@");
            try {
                temp_sign=Integer.parseInt(text.substring(0,p));
            }catch (Exception e){
                /**
                 * 利用String转int的异常,实现等待超时
                 */
                count_time+=read_time;
                System.out.println("已等待"+(count_time/1000)+"秒");
                if(count_time>=time_out&&sign==0){
                    System.out.println("超时退出");
                    System.exit(0);
                }
                continue;
            }
            /**
             * 设置文件名
             */
            sign=temp_sign;
            if(file_target.equals("")){
                setFile_target(text.substring(p+1));
            }
        }
        /**
         * 创建文件
         */
        File target=new File(dir_out+file_target);
        if(target.exists())target.delete();
        target.createNewFile();
        System.out.println("创建输出路径及文件");
        /**
         * 初始化剪切板,解码器,写入流等参数
         */
        BufferedOutputStream bo=new BufferedOutputStream(new FileOutputStream(target));
        /**
         * 开始接收数据
         */
        while (true){
            delay(read_time);
            String text=getClipboardText();
            int temp_sign=0;
            int p=text.indexOf("@");
            temp_sign=Integer.parseInt(text.substring(0,p));
            if(temp_sign<0)break;//结束
            else if(sign==temp_sign)continue;//重复
            else sign=temp_sign;//数据更新
            System.out.println("数据包:"+sign);
            bo.write(decoder.decode(text.substring(p+1)));
            bo.flush();
        }
        bo.flush();
        bo.close();
        System.out.println("接收的文件大小"+target.length());
        target=null;
    }


    /**
     *  获取剪切板数据
     * @return
     * @throws IOException
     * @throws UnsupportedFlavorException
     */
    public String getClipboardText() throws IOException, UnsupportedFlavorException {
        Transferable context=cb.getContents(null);
        if(context!=null&&context.isDataFlavorSupported(DataFlavor.stringFlavor)){
            return  (String)context.getTransferData(DataFlavor.stringFlavor);
        }
        return "";
    }


    /**
     *
     * @param time  程序等待时间
     */
    public void delay(int time){
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    /**
     * 创建文件夹
     * @param dir_path   文件夹路径
     * @throws IOException
     */
    public void createDir(String dir_path) throws IOException {
        File dir=new File(dir_path);
        if(!dir.exists()) dir.mkdirs();
    }

    public String getFile_target() {
        return file_target;
    }

    public void setFile_target(String file_target) {
        this.file_target = file_target;
    }
    public int getRead_time() {
        return read_time;
    }

    public void setRead_time(int read_time) {
        this.read_time = read_time;
    }

    public int getTime_out() {
        return time_out;
    }

    public void setTime_out(int time_out) {
        this.time_out = time_out;
    }
}

三、测试:

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    new SendData("D:/456.zip" ).start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    new ReceiveData().start();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (UnsupportedFlavorException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值