Android-->UDP协议的Socket数据传输

阅读之前,你已经了解了UDP的相关知识;

UDP数据传输时,数据包的大小是有限制的65535, 大概是64k的内容

当数据太大时,需要分包机制,后续补充…如果你有更好的分包方法,请分享给我~谢谢!

接收端的代码:


public class UdpServerThread2 extends Thread {

    public static final PrintStream p = System.out;
    private static final int DATA_LEN = 1228800;
    public static String serverIp = "192.168.124.78";
    public static int serverPort = 8089;
    private static Object lock = new Object();
    private final SaveFileThread fileThread;
    byte[] data;
    DatagramSocket socket;
    private boolean isExit = false;

    private UdpServerThread2() throws SocketException {
        //创建一个 socket,监听 serverPort端口
        socket = new DatagramSocket(serverPort);

        //创建一个保存数据到文件的线程,非必须
        fileThread = new SaveFileThread();
        fileThread.start();
    }

    //启动方法
    public static void main(String... args) {
        try {
            new UdpServerThread2().start();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (!isExit) {
            data = new byte[DATA_LEN];
            //创建一个用于接收数据的数据包对象,需要指定长度
            DatagramPacket packet = new DatagramPacket(data, DATA_LEN);
            try {
                p.println("等待中...");
                //等待接收数据...
                socket.receive(packet);
//                String s = new String(data);
//                p.println("收到数据包:" + s + " 大小:" + packet.getLength() + " 字节" + " 长度:" + s.length());
                p.println("收到数据包大小:" + packet.getLength() + " 字节");
                //将数据保存到文件
                fileThread.saveData(data, packet.getLength());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 保存文件的线程
     */
    class SaveFileThread extends Thread {
        private Vector<byte[]> saveData;
        private volatile int length;

        public SaveFileThread() {
            this.saveData = new Vector<>();

            File png = new File("png");
            if (!png.exists()) {
                png.mkdirs();
            }

        }

        private String getSaveFileName() {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH-mm-ss-SSS");
            String format = simpleDateFormat.format(new Date());
            return (format + ".png");
        }

        public void saveData(byte[] data, int len) {
            saveData.add(data);
            length = len;
        }

        @Override
        public void run() {
            while (!isExit) {
                if (!saveData.isEmpty()) {
                    byte[] data = saveData.remove(0);
                    try {
                        String fileName = getSaveFileName();
                        FileOutputStream outputStream = new FileOutputStream(new File("png" + File.separator + fileName));

                        outputStream.write(data, 0, length);
                        outputStream.close();
                        p.println("保存至:-->" + fileName);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

发送端的代码


public class UdpSendThread extends Thread {

    private static Object lock = new Object();
    private static UdpSendThread sendThread;

    private volatile boolean isExit = false;
    private Vector<int[]> sendDataInt;
    private Vector<byte[]> sendDataByte;
    private DatagramSocket socket;

    private int port = 8089;
    private String ip = "192.168.124.78";

    private UdpSendThread() {
        sendDataInt = new Vector<>();
        sendDataByte = new Vector<>();
        try {
            socket = new DatagramSocket();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public static UdpSendThread getInstance() {
        if (sendThread == null) {
            synchronized (lock) {
                if (sendThread == null) {
                    sendThread = new UdpSendThread();
                    sendThread.start();
                }
            }
        }

        return sendThread;
    }

    /**
     * 将int数值转换为占四个字节的byte数组,本方法适用于(低位在前,高位在后)的顺序。 和bytesToInt()配套使用
     *
     * @param value 要转换的int值
     * @return byte数组
     */
    public static byte[] intToBytes(int value) {
        byte[] src = new byte[4];
        src[3] = (byte) ((value >> 24) & 0xFF);
        src[2] = (byte) ((value >> 16) & 0xFF);
        src[1] = (byte) ((value >> 8) & 0xFF);
        src[0] = (byte) (value & 0xFF);
        return src;
    }

    /**
     * byte数组中取int数值,本方法适用于(低位在前,高位在后)的顺序,和和intToBytes()配套使用
     *
     * @param src    byte数组
     * @param offset 从数组的第offset位开始
     * @return int数值
     */
    public static int bytesToInt(byte[] src, int offset) {
        int value;
        value = (int) ((src[offset] & 0xFF)
                | ((src[offset + 1] & 0xFF) << 8)
                | ((src[offset + 2] & 0xFF) << 16)
                | ((src[offset + 3] & 0xFF) << 24));
        return value;
    }

    public static byte[] intsToBytes(int[] values) {
        byte[] src = new byte[4 * values.length];
        for (int i = 0; i < values.length; i++) {
            byte[] bytes = intToBytes(values[i]);

            for (int j = 0; j < bytes.length; j++) {
                src[i * 4 + j] = bytes[j];
            }
//            System.arraycopy(bytes, 0, src, i * 4, bytes.length);
        }

        return src;
    }


    public void send(int[] data) {
        try {
            //数据类型的转换
            byte[] bytes = intsToBytes(data);
            //创建一个数据包,包含数据,端口,目标地址
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
            packet.setPort(port);
            packet.setAddress(InetAddress.getByName(ip));
            //发送...
            socket.send(packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void send(byte[] data) {
        sendDataByte.add(data);
    }

    public void exit() {
        isExit = true;
    }

    @Override
    public void run() {
        while (!isExit) {
//            if (!sendDataInt.isEmpty()) {
//                int[] data = sendDataInt.remove(0);
//
//            }
            if (!sendDataByte.isEmpty()) {
                try {
                    byte[] data = sendDataByte.remove(0);
                    DatagramPacket packet = new DatagramPacket(data, data.length);
                    packet.setPort(port);
                    packet.setAddress(InetAddress.getByName(ip));
                    socket.send(packet);
                    System.out.println("发送数据长度:" + data.length + "字节");
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

至此: 文章就结束了,如有疑问: QQ群:274306954 欢迎您的加入.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值