Java使用ByteBuffer从GPS设备解码字节

时间:2019-01-19 22:34:04

标签: java gps udp unpack

我遇到了解码从GPS设备发送到我的Java UDP侦听器程序的字节的问题。我可以提取一些信息,但是对于其他信息,我无法理解如何执行此操作。设备手册中的数据格式如下:

Name       | Type          | Length
length:    | short         | 2
cmd:       | short         | 2
enabled:   | unsigned char | 1
alarm:     | unsigned char | 1
speed:     | char          | 1
direction: | short         | 2
longitude: | double        | 4
latitude:  | double        | 4
datetime:  | long          | 4
userid:    | char          | 11
iostate:   | char          | 1
oilstate:  | char          | 1

在我的程序中,我可以解码长度,命令,警报,速度,方向和设备。我被困在纬度,经度和日期时间上,需要一些帮助。我得到的价值与正确的价值完全相去甚远。使用struct.unpack函数在python上没有任何问题。

函数中的代码如下:

private void SetupUDP() throws IOException {
        String message;
        // Setup UDP Stuff and listen on all interfaces
        DatagramSocket serverSocket = new DatagramSocket(9876, InetAddress.getByName("0.0.0.0"));
        byte[] receiveData = new byte[1024];
        while(true) {
            // Start receiving UDP packets from devices
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            serverSocket.receive(receivePacket);

            ByteBuffer data = ByteBuffer.wrap(receivePacket.getData());
            data.order(ByteOrder.LITTLE_ENDIAN);
            if (receivePacket.getLength() == 15) {
                short len = data.getShort(0);
                short cmd = data.getShort(2);
                String device = "";
                for (int x=4; x < 14; x++) {
                    byte b = data.get(x);
                    device += (char) b;
                }
                System.out.println(len + " " + cmd + " -- " + device);
            }
            if (receivePacket.getLength() == 34) {
                short len = data.getShort(0);
                short cmd = data.getShort(2);
                byte benabled = data.get(4);
                int enabled = (int) benabled;
                byte balarm = data.get(5);
                // Alarm (OK)
                int alarm =  Math.abs((int) balarm);
                // Speed (OK)
                byte bspeed = data.get(6);
                int speed = (int) bspeed;
                // Direction (OK)
                short direction = data.getShort(7);
                // Coordinates
                double longitude = data.getDouble(9);
                double latitude = data.getDouble(13);
                // Device ID (OK)
                String device = "";
                for (int x=21; x < 31; x++) {
                    byte bdevice = data.get(x);
                    device += (char) bdevice;
                }

                // Datetime (testing)
                int ddatetime = data.get(17);
                Date datetime = new Date(ddatetime * 1000);
                //System.out.println("-->" + datetime + ", " + longitude);
                System.out.println(len + " " + cmd + " " + enabled + " " + alarm + " " + speed + " " + direction + " " + longitude + " " + latitude + " " + datetime + " " + device);
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

您正在读取的纬度和经度分别为8个字节,说明为4。 Java中的EmbeddedResourcedouble中的getDouble是8个字节,您需要ByteBuffer

当您阅读过多时,这也会破坏数据。