java基于UDP协议发送、接收数据和附件(图片),byte数组

    UDP协议是非连接协议,不与目标地址建立连接,简单说就是只负责发送给目标地址数据,不等待目标返回结果。每次发送只能是少量数据,不过可以少量多次发送,发送几M的图片还是没问题的。

    以下是我发送数据和接收数据的相关代码,以供参考。

  • java基于UDP协议发送数据(客户端):

    /***
     * 
     * @param licensePlate  业务数据
     * @param platPicUrls   业务图片地址
     * @param pudipconfig   目标地址ip、端口号,服务地址的端口号(用于监听是否有数据进入)
     * @throws Exception
     */
    public void sendAllUDP(LicensePlate licensePlate, List platPicUrls,Pudipconfig pudipconfig) throws Exception {
        //初始化用于发送数据
        byte[] buf = new byte[UDPUtils.BUFFER_SIZE];
        //初始化用户接收数据
        byte[] receiveBuf = new byte[100];
        //定义照片
        RandomAccessFile accessFile = null;
        //定义服务端
        DatagramSocket dsk = null;
        //定义数据包
        DatagramPacket dpk;
        //定义读取大小
        int readSize;

        try {
            //初始化服务端  参数为端口号,作用在于监听该端口号是否有数据交互
            dsk = new DatagramSocket(Integer.parseInt(pudipconfig.getExt1()));
            //初始化数据包  参数为:byte类型存放数据,数据大小,目标地址,目标端口
            dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName(pudipconfig.getIpaddress()), Integer.parseInt(pudipconfig.getIpport())));

            //将需要发送的业务数据转成byte类型并放入数据包
            dpk.setData(licensePlate.getLicenseplatenumber().getBytes("UTF-8"),0,licensePlate.getLicenseplatenumber().getBytes().length);
            //发送数据
            dsk.send(dpk);

            //为保证数据准确性,在每次发送数据后等待目标地址反向调用发送端的ip+端口,并用receiveBuf存下返回的数据是否成功
            //该方式只适用于单对单传输
            dpk.setData(receiveBuf, 0, receiveBuf.length);
            //等待目标地址返回数据
            dsk.receive(dpk);

            // 验证服务端返回成功   成功则进入下一步发送附件(图片)数据
            if(UDPUtils.isEqualsByteArray("success_title".getBytes(),receiveBuf,dpk.getLength())){
                //记录发送附件数次数
                int sendCount = 0;

                //以下为发送附件(图片)部分
                //获取保存文件夹路径
                String t=Thread.currentThread().getContextClassLoader().getResource("").getPath();
                int num=t.indexOf("jeesite/WEB-INF");

                //遍历发送多个附件(图片)
                for (String platPicUrl : platPicUrls) {
                    sendCount++;
//                accessFile = new RandomAccessFile(platPicUrl,"r");
                    //获取车牌照文件
                    accessFile = new RandomAccessFile(t.substring(1,num-1)+java.net.URLDecoder.decode(platPicUrl, "UTF-8"),"r");

                    //循环读取车牌照,目的是附件需要多次发送才能完成,UDP协议一次只能发送最多64k的数据
                    while ((readSize = accessFile.read(buf,0,buf.length)) != -1){
                        System.out.println(Arrays.toString(buf));
                        //发送附件数据
                        dpk.setData(buf,0,readSize);
                        dsk.send(dpk);

                        //每次发送都等待目标地址返回成功标识
                        dpk.setData(receiveBuf, 0, receiveBuf.length);
                        dsk.receive(dpk);
                        // 验证服务端返回成功
                        if(!UDPUtils.isEqualsByteArray("success_pic".getBytes(),receiveBuf,"success_pic".getBytes().length))
                            throw new Exception("车牌照验证错误:success_pic");
                    }
                    System.out.println(sendCount);
                    //发送一个附件发送结束标识
                    dpk.setData("end_pic".getBytes("UTF-8"));
                    dsk.send(dpk);

                    //等待目标地址返回一个附件结束验证成功
                    dpk.setData(receiveBuf, 0, receiveBuf.length);
                    dsk.receive(dpk);
                    // 验证服务端返回成功  一张照片成功
                    if(!UDPUtils.isEqualsByteArray("success_end".getBytes(),receiveBuf,"success_end".getBytes().length))
                        throw new Exception("附件验证错误:success_end");
                }

                //发送验证所有数据发送完成,程序结束
                dpk.setData("end_all".getBytes("UTF-8"), 0, "end_all".getBytes().length);
                dsk.send(dpk);
            } else {
                throw new Exception("附件发送失败!");
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(accessFile != null)
                    accessFile.close();
                if(dsk != null)
                    dsk.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • java基于UDP协议接收数据(服务端):

/**
     * 作为客户端接收数据
     */
    public void getUDP2(){
        byte[] buf = new byte[UDPUtils.BUFFER_SIZE];
        DatagramPacket dpk = null;
        DatagramSocket dsk = null;
        BufferedOutputStream bos = null;
        try {
            //初始化数据包并设定目标地址ip、端口号   作为服务端可以不需要设定目标地址,这里设定是为了给客服端做成功、失败校验,保证数据的准确性
            dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("192.168.0.110"), 8198));
            //初始化服务端并设定监听端口号
            dsk = new DatagramSocket(UDPUtils.PORT2);
            //用于给附件定义名称
            int flag = 0;
            //给定无限循环 不间断接收数据,一直保持监听状态
            while (true){
                System.out.println(flag);
                System.out.println("wait client1 ...."+ new String(buf,0,20));
                //等待接收客服端发送数据
                //receive是一个阻塞型的方法,没有接收到数据包之前会一直等待。 数据实际上就是存储到了byte的自己数组中了。
                dsk.receive(dpk);

                //发送给客服端接收成功
                dpk.setData("success_title".getBytes(), 0, "success_title".getBytes().length);
                dsk.send(dpk);

                /**接收附件循环*/
                while (true){
                    flag ++;
                    //等待附件
                    dpk.setData(buf,0, buf.length);
                    System.out.println("wait client2 ...."+new String(buf,0,20));
                    dsk.receive(dpk);
                    int readSize = 0;
                    int readCount = 0;
                    int flushSize = 0;
                    if (UDPUtils.isEqualsByteArray("end_all".getBytes(), buf, "end_all".getBytes().length)){
                        System.out.println("server end ...");
                        break;
                    } else {
                        //创建文件
                        bos = new BufferedOutputStream(new FileOutputStream("D:/demoPic/2013_" + flag+".jpg"));
                    }

                    while((readSize = dpk.getLength()) != 0){
                        // validate client send exit flag
                        if(UDPUtils.isEqualsByteArray("end_pic".getBytes(), buf, readSize)){
                            System.out.println("server exit ...");
                            // send exit flag
                            dpk.setData("success_end".getBytes(), 0, "success_end".getBytes().length);
                            dsk.send(dpk);
                            break;
                        }

                        //将接收到的数据写入文件中
                        bos.write(buf, 0, readSize);

                        if(++flushSize % 1000 == 0){
                            flushSize = 0;
                            bos.flush();
                        }
                        dpk.setData("success_pic".getBytes(), 0, "success_pic".getBytes().length);
                        dsk.send(dpk);

                        dpk.setData(buf,0, buf.length);
                        System.out.println("receive count of "+ ( ++readCount ) +" !");
                        System.out.println("wait client3 ...." + new String(buf,0,20));
                        dsk.receive(dpk);
                    }

                    // last flush
                    bos.flush();

                    if(UDPUtils.isEqualsByteArray("end_all".getBytes(), buf, readSize)){
                        System.out.println("server end4 ...");
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            try {
                if(bos != null)
                    bos.close();
                if(dsk != null)
                    dsk.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 

你可能感兴趣的:(JAVA)