Java接收UDP数据解码

1.Java接收UDP数据解码主要使用到以下三个方法:
(1)

public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer>

(2)

  public static ByteBuffer wrap(byte[] array,int offset, int length)
    {
        try {
            return new HeapByteBuffer(array, offset, length);
        } catch (IllegalArgumentException x) {
            throw new IndexOutOfBoundsException();
        }
    }

(3)

public final ByteBuffer order(ByteOrder bo) {
        bigEndian = (bo == ByteOrder.BIG_ENDIAN);
        nativeByteOrder =
            (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
        return this;
    }

以上方法都是Java编译工具自带的,本文使用的编译工具是IDE。
2.代码示例如下所示:

public ArrayList<DeviceStatus> analysis(DatagramPacket packet) {
        byte[] buffer = packet.getData();// 接收到的UDP数据,然后解码
        short head = ByteBuffer.wrap(buffer, 0, 2).order(ByteOrder.LITTLE_ENDIAN).getShort();//帧头0x13ec
        if(head == 0x13ec)/*接收服务状态格式数据并解析*/
       {
            NetWorkState netWorkState = UdpCache.getDeviceStatusData();
            byte send_cont = ByteBuffer.wrap(buffer, 2, 1).get();//帧序列号0~255
            byte recoding_state = ByteBuffer.wrap(buffer, 3, 1).order(ByteOrder.BIG_ENDIAN).get();//录音状态
            int self_server_ip = ByteBuffer.wrap(buffer,4,4).order(ByteOrder.BIG_ENDIAN).getInt();//本地服务IP
            int far_server_ip = ByteBuffer.wrap(buffer,8,4).order(ByteOrder.BIG_ENDIAN).getInt();//远端服务IP
            int multicast_ip = ByteBuffer.wrap(buffer,12,4).order(ByteOrder.BIG_ENDIAN).getInt();//组播地址
            int network_ip = ByteBuffer.wrap(buffer,16,4).order(ByteOrder.BIG_ENDIAN).getInt();//网管地址
            int pc_worktop_ip = ByteBuffer.wrap(buffer,20,4).order(ByteOrder.BIG_ENDIAN).getInt();//操作台地址
            int bit_ip = ByteBuffer.wrap(buffer,24,4).order(ByteOrder.BIG_ENDIAN).getInt();//BIT地址
            int self_port = ByteBuffer.wrap(buffer,28,4).order(ByteOrder.LITTLE_ENDIAN).getInt();//本地端口号
            int far_port = ByteBuffer.wrap(buffer,32,4).order(ByteOrder.LITTLE_ENDIAN).getInt();//远端服务器端口号
            int web_port = ByteBuffer.wrap(buffer,36,4).order(ByteOrder.LITTLE_ENDIAN).getInt();//网管端口
            int pc_port = ByteBuffer.wrap(buffer,40,4).order(ByteOrder.LITTLE_ENDIAN).getInt();//操作台端口
            int bit_port = ByteBuffer.wrap(buffer,44,4).order(ByteOrder.LITTLE_ENDIAN).getInt();//BIT端口号
            String version = new String(Arrays.copyOfRange(buffer,48,48 + 8)).trim();//软件版本v3.00
            int online_state = ByteBuffer.wrap(buffer,56,4).order(ByteOrder.LITTLE_ENDIAN).getInt();//设备在线状态
            byte ser_online_kun_it = ByteBuffer.wrap(buffer,60,1).order(ByteOrder.BIG_ENDIAN).get();//主副服务器及便携设备在线状态
            byte a_employ = ByteBuffer.wrap(buffer,61,1).get();//A型终端信道使用标志,空闲0xFF,占用0或32
            byte d_employ = ByteBuffer.wrap(buffer,62,1).get();//对讲终端信道占用标志,空闲0xFF,占用时为设备编号
            byte playback = ByteBuffer.wrap(buffer,63,1).order(ByteOrder.BIG_ENDIAN).get();//回放模式,为1时回放,2为回演,0时不操作
            byte connect_net_state = ByteBuffer.wrap(buffer,64,1).order(ByteOrder.BIG_ENDIAN).get();//联网状态
            byte server_id = ByteBuffer.wrap(buffer,65,1).order(ByteOrder.BIG_ENDIAN).get();//服务软件ID号
            short end = ByteBuffer.wrap(buffer, 66, 2).order(ByteOrder.LITTLE_ENDIAN).getShort();//帧尾0x13ec

            //将接收到的数据放入对象netWorkState中
            netWorkState.setHead(head);
            netWorkState.setSend_cont(send_cont);
            netWorkState.setRecoding_state(recoding_state);
            netWorkState.setSelf_server_ip(ByteUtils.intToIp(self_server_ip));
            netWorkState.setFar_server_ip(ByteUtils.intToIp(far_server_ip));
            netWorkState.setMulticast_ip(ByteUtils.intToIp(multicast_ip));
            netWorkState.setNetwork_ip(ByteUtils.intToIp(network_ip));
            netWorkState.setPc_worktop_ip(ByteUtils.intToIp(pc_worktop_ip));
            netWorkState.setBit_ip(ByteUtils.intToIp(bit_ip));
            netWorkState.setSelf_port(self_port);
            netWorkState.setFar_port(far_port);
            netWorkState.setWeb_port(web_port);
            netWorkState.setPc_port(pc_port);
            netWorkState.setBit_port(bit_port);
            netWorkState.setVersion(version.trim());
            netWorkState.setOnline_state(online_state);
            netWorkState.setSer_online_kun_it(ser_online_kun_it);
            netWorkState.setA_employ(a_employ);
            netWorkState.setD_employ(d_employ);
            netWorkState.setPlayback(playback);
            netWorkState.setConnect_net_state(connect_net_state);
            netWorkState.setServer_id(server_id);
            netWorkState.setEnd(end);
        }
        /**---------------------------------------------------------------------------------------------------------**/
        //接收回执指令帧数据
        if (head == 0x11ea){
            CommandReceipt commandReceipt = UdpCache.getCommandReceiptData();
            byte deviceNum = ByteBuffer.wrap(buffer,2,1).order(ByteOrder.BIG_ENDIAN).get();//设备编号
            byte frameNum = ByteBuffer.wrap(buffer,3,1).order(ByteOrder.BIG_ENDIAN).get();//帧序列号
            byte receiptClass = ByteBuffer.wrap(buffer,4,1).order(ByteOrder.BIG_ENDIAN).get();//回执类别
            byte commandMeaning = ByteBuffer.wrap(buffer,5,1).order(ByteOrder.BIG_ENDIAN).get();//指令含义
            short backups_1 = ByteBuffer.wrap(buffer,6,2).order(ByteOrder.LITTLE_ENDIAN).getShort();//备份1
            byte[] fileName = Arrays.copyOfRange(buffer,8,32 + 8);//文件名
            long frameLong = ByteBuffer.wrap(buffer,40,8).order(ByteOrder.LITTLE_ENDIAN).getLong();//帧长度
            long playSeat = ByteBuffer.wrap(buffer,48,8).order(ByteOrder.LITTLE_ENDIAN).getLong();//当前播放位置
            short backups_2 = ByteBuffer.wrap(buffer,56,2).order(ByteOrder.LITTLE_ENDIAN).getShort();//备份2
            short frameEnd = ByteBuffer.wrap(buffer,58,2).order(ByteOrder.LITTLE_ENDIAN).getShort();//帧尾

            commandReceipt.setFrame(head);
            commandReceipt.setDevice_num(deviceNum);
            commandReceipt.setFrame_num(frameNum);
            commandReceipt.setReceipt_class(receiptClass);
            commandReceipt.setCommand_meaning(commandMeaning);
            commandReceipt.setBackups1(backups_1);
            commandReceipt.setFile_name(fileName);
            commandReceipt.setFrame_long(frameLong);
            commandReceipt.setPlay_set(playSeat);
            commandReceipt.setBackups2(backups_2);
            commandReceipt.setFrame_end(frameEnd);
            System.out.println("接收回执数据:" + commandReceipt.getFile_name());
        }
        /**---------------------------------------------------------------------------------------------------------**/
        ArrayList<DeviceStatus> deviceStatuses = new ArrayList<DeviceStatus>();//定义数组列表deviceStatuses存放设备状态信息
        if(head == 0x15ef) //接收终端状态格式数据
        {
            WebWorkState webWorkState = UdpCache.getDeviceStatusData1();
            byte device_number = ByteBuffer.wrap(buffer,2,1).order(ByteOrder.BIG_ENDIAN).get();//设备编号
            byte serial_number = ByteBuffer.wrap(buffer,3,1).order(ByteOrder.BIG_ENDIAN).get();//帧序列号
            int online_state = ByteBuffer.wrap(buffer,4,4).order(ByteOrder.LITTLE_ENDIAN).getInt();//设备在线状态
            byte[] SystemStatus = Arrays.copyOfRange(buffer,8,1452 + 8);//系统所有设备工作状态(33x44字节)
            short reserve = ByteBuffer.wrap(buffer, 1460, 2).order(ByteOrder.LITTLE_ENDIAN).getShort();//备份
            short backend = ByteBuffer.wrap(buffer, 1462, 2).order(ByteOrder.LITTLE_ENDIAN).getShort();//帧尾

            //定义数组列表deviceStatuses存放设备状态信息
            // ArrayList<DeviceStatus> deviceStatuses = new ArrayList<DeviceStatus>();
            for(int i = 0;i < 33;i++)
            {
                DeviceStatus deviceStatus = new DeviceStatus();
                deviceStatus.setName("" + i);
                deviceStatus.setPattern(ByteBuffer.wrap(SystemStatus,44 * i,1).get());//通讯模式
                deviceStatus.setRecord(ByteBuffer.wrap(SystemStatus,44 * i + 1,1).get());//录音状态
                deviceStatus.setOn_link(ByteBuffer.wrap(SystemStatus,44 * i + 2,1).get());//网络连接回执状态
                deviceStatus.setWork(ByteBuffer.wrap(SystemStatus,44 * i + 3,1).get());//运行状态
                deviceStatus.setX(Math.round(ByteBuffer.wrap(SystemStatus, 44 * i + 4, 4).order(ByteOrder.LITTLE_ENDIAN).getFloat() * 100 / 100f));
                deviceStatus.setA(Math.round(ByteBuffer.wrap(SystemStatus, 44 * i + 8, 4).order(ByteOrder.LITTLE_ENDIAN).getFloat() * 100 / 100f));
                deviceStatus.setD(Math.round(ByteBuffer.wrap(SystemStatus, 44 * i + 12, 4).order(ByteOrder.LITTLE_ENDIAN).getFloat() * 100 / 100f));
                deviceStatus.setC(Math.round(ByteBuffer.wrap(SystemStatus, 44 * i + 16, 4).order(ByteOrder.LITTLE_ENDIAN).getFloat() * 100 / 100f));
                deviceStatus.setSelf_ip(ByteUtils.intToIp(ByteBuffer.wrap(SystemStatus, 44 * i + 20, 4).order(ByteOrder.BIG_ENDIAN).getInt()));
                deviceStatus.setServer_ip1(ByteUtils.intToIp(ByteBuffer.wrap(SystemStatus, 44 * i + 24, 4).order(ByteOrder.BIG_ENDIAN).getInt()));
                deviceStatus.setBit_ip(ByteUtils.intToIp(ByteBuffer.wrap(SystemStatus, 44 * i + 28, 4).order(ByteOrder.BIG_ENDIAN).getInt()));
                deviceStatus.setGroup_ip(ByteUtils.intToIp(ByteBuffer.wrap(SystemStatus, 44 * i + 32, 4).order(ByteOrder.BIG_ENDIAN).getInt()));
                deviceStatus.setGateway_ip(ByteUtils.intToIp(ByteBuffer.wrap(SystemStatus, 44 * i + 36, 4).order(ByteOrder.BIG_ENDIAN).getInt()));
                deviceStatus.setServer_ip2(ByteUtils.intToIp(ByteBuffer.wrap(SystemStatus, 44 * i + 40, 4).order(ByteOrder.BIG_ENDIAN).getInt()));
                deviceStatuses.add(deviceStatus);

            }
            webWorkState.setHead(head);
            webWorkState.setDevice_number(device_number);
            webWorkState.setSerial_number(serial_number);
            webWorkState.setOnline_state(online_state);
            webWorkState.setSystemStatus(deviceStatuses);
            webWorkState.setReserve(reserve);
            webWorkState.setBackend(backend);

            //System.out.println("接收的数据:" + webWorkState.getSystemStatus());
        }
        return deviceStatuses;
    }

3.Java发送UDP数据时需要注意的是对发送数据的组帧和大小端问题,要把对象序列化到数组中去,然后调用发送的方法发送数据,代码示例如下所示:

/**-----------------------------------------------------------------------------------------------------------------**/
	/**
	 * 实现设备状态信息显示
	 * @param request
	 * @param map
	 * @return
	 */
/**-----------------------------------------------------------------------------------------------------------------**/
	@RequestMapping("/info")
	public  String info(HttpServletRequest request,ModelMap map){
		WebCommand webCommand = new WebCommand();//实列化对象
		UdpSimpleClient udpSimpleClient = new UdpSimpleClient();//实列化发送方法接口对象
		/**************************************************************************/
		                         /**
								  * 查询终端上报帧格式数据
								  * */
		/**************************************************************************/
		//定义数据类型值
		short head = 0x14ed;
		byte num = 0x21;
		byte Num = 0;
		Num++;
		byte clas = 0x1D;//指令类别
		byte matter = 0x54;//指令含义,T的ascii为84十六进制为0x54,即终端0x54
		Short seat = 0x0000;
		byte[] object = new byte[32];//操作目标
		short reserve = 0x0000;//备份
		short end =  0x13ec;//帧尾
		/**************************************************************************/
		//将数据放入webCommand对象中
		webCommand.setHead(head);
		webCommand.setCarNum(num);
		webCommand.setSendCnt(Num);
		webCommand.setClasses(clas);
		webCommand.setMatter(matter);
		webCommand.setPlaySeat(seat);
		webCommand.setObjective(object);
		webCommand.setReserve(reserve);
		webCommand.setBackEnd(end);
		/**************************************************************************/
		// 对象序列化到字节数组
		ByteBuffer byteBuffer = ByteBuffer.allocate(44).order(ByteOrder.LITTLE_ENDIAN);//小端序列
		byteBuffer.putShort(webCommand.getHead());
		byteBuffer.put(webCommand.getCarNum());
		byteBuffer.put(webCommand.getSendCnt());
		byteBuffer.put(webCommand.getClasses());
		byteBuffer.put(webCommand.getMatter());
		byteBuffer.putShort(webCommand.getPlaySeat());
		byteBuffer.put(webCommand.getObjective());
		byteBuffer.putShort(webCommand.getReserve());
		byteBuffer.putShort(webCommand.getBackEnd());
		byte[] array = byteBuffer.array();
		udpSimpleClient.sendMessage(array);//发送终端查询帧
        /*************************************************************************************************/
		                                       /**
												* 查询服务上报帧格式数据
												* */
        /************************************************************************************************/
		//定义数据类型值
		short head1 = 0x14ed;
		byte num1 = 0x21;
		byte Num1 = 0;
		Num1++;
		byte clas1 = 0x1D;//指令类别
		byte matter1 = 0x53;//指令含义,S的ascii为83十六进制为0x53,即服务
		Short seat1 = 0x0000;
		byte[] object1 = new byte[32];//操作目标
		short reserve1 = 0x0000;//备份
		short end1 =  0x13ec;//帧尾
		/**************************************************************************/
		//将数据放入webCommand对象中
		webCommand.setHead(head1);
		webCommand.setCarNum(num1);
		webCommand.setSendCnt(Num1);
		webCommand.setClasses(clas1);
		webCommand.setMatter(matter1);
		webCommand.setPlaySeat(seat1);
		webCommand.setObjective(object1);
		webCommand.setReserve(reserve1);
		webCommand.setBackEnd(end1);
		/**************************************************************************/
		// 对象序列化到字节数组
		ByteBuffer byteBuffer1 = ByteBuffer.allocate(44).order(ByteOrder.LITTLE_ENDIAN);//小端序列
		byteBuffer1.putShort(webCommand.getHead());
		byteBuffer1.put(webCommand.getCarNum());
		byteBuffer1.put(webCommand.getSendCnt());
		byteBuffer1.put(webCommand.getClasses());
		byteBuffer1.put(webCommand.getMatter());
		byteBuffer1.putShort(webCommand.getPlaySeat());
		byteBuffer1.put(webCommand.getObjective());
		byteBuffer1.putShort(webCommand.getReserve());
		byteBuffer1.putShort(webCommand.getBackEnd());
		byte[] array1 = byteBuffer.array();
		udpSimpleClient.sendMessage(array1);
		System.out.println("Data:" +array1);
		/**************************************************************************/
		                       /**
								* 获取终端上报帧格式数据
								* */
		/**************************************************************************/
		//必须先发送命令,再实例化获取数据
        NetWorkState netWorkState = UdpCache.getDeviceStatusData();
		WebWorkState webWorkState = UdpCache.getDeviceStatusData1();
		UdpServer udpServer = new UdpServer();
		ArrayList<DeviceStatus> analysis = udpServer.analysis(packet);
		//按位与;作用:清零和取特定值,按位获取32个终端设备在线状态,
		int result = webWorkState.getOnline_state();
		byte server_state = netWorkState.getSer_online_kun_it();
		int b[] = new int[33];
		for (int i=0;i<33;i++)
		{
			if (i < 32)
			{
				b[i] = (result >> i) & 0x01;
			}
			else
			{
				b[i] = (server_state >> 2) & 0x01;
			}
		}
		map.put("state",b);
		/*----------------------------------------------------*/
		//获取系统时间
		Date DateTime = new Date();
		SimpleDateFormat DateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String nowTime = DateTimeFormat.format(DateTime);
		map.put("maptime",nowTime);
		/*----------------------------------------------------*/
		map.put("map1", analysis);
		return "info";
	}

4.Java接收UDP数据解码源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九点两刻

你的支持是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值