如何在Java中读取网络流数据(协议包)

如何在Java中读取网络流数据(协议包),java,networking,networkstream,Java,Networking,Networkstream,我正在解码某个gps设备用来通信的协议。 现在,我正在分析它发送的第一个数据包。我能读,但我想我读得不好 以下是我到目前为止得到的信息: public static String toHex(byte[] bytes) { BigInteger bi = new BigInteger(1, bytes); return String.format("%0" + (bytes.length << 1) + "X", bi); } private void Pr

我正在解码某个gps设备用来通信的协议。 现在,我正在分析它发送的第一个数据包。我能读,但我想我读得不好

以下是我到目前为止得到的信息:

    public static String toHex(byte[] bytes) {
    BigInteger bi = new BigInteger(1, bytes);
    return String.format("%0" + (bytes.length << 1) + "X", bi);
}

private void ProcessInitialPacket(){
            int port = 1954;
    System.out.println("Listening on port :"+port);
    byte[] data =  new byte[17];
    byte[] ackPacket = new byte[2];
    byte[] dataPacket= new byte[15];
    try {
        ServerSocket sSocket = new ServerSocket(port);
        Socket cSocket = sSocket.accept();          
        DataInputStream dataIN = new DataInputStream(cSocket.getInputStream());
        int packetSize=dataIN.read(data,0,data.length);         
        System.arraycopy(data, 0, ackPacket, 0, 2);
        System.arraycopy(data,2,dataPacket,0,15);

        System.out.println("Total packet size: "+ packetSize);
        System.out.println("ACK PACKET : "+ toHex(ackPacket));
        System.out.println("DATA PACKET: "+ toHex(dataPacket));
        System.out.println("FULL PACKET: "+ toHex(data));
    } catch (IOException e) { 
        e.printStackTrace();
    }
}
-初始化会话-- 监听端口:1954年

总数据包大小:17

确认数据包:000F

数据包:333532383438303236323631393534

完整数据包:000F333532383438303236323631393534

------闭门会议------------

现在,我的问题是:

这里发生的情况是设备发送[0x00][0x0F]xxxxxxxxxxxxx 其中xxxxxxx是其imei(数据包)。 我的问题是数据包上有太多的3,所以真正有效的输出是

352848026261954


您可以通过删除3’s获得。我的问题是:这种行为是来自我的代码还是协议的一部分?我可以通过编程来纠正这个问题,但我想知道有一种方法,代码可以导致这些额外的3

这是ASCII数字编码。0正在作为“0”传输,即0x30。1正在作为0x31传输。因此,您对数据格式的理解是不正确的。

这是ASCII数字编码。0正在作为“0”传输,即0x30。1正在作为0x31传输。因此,您对数据格式的理解是不正确的。

您看到的是需要解码为数字的ascii值的十六进制。作为十进制的字符“0”是48或十六进制0x30,“9”之前作为十进制的字符是57或十六进制的字符是0x39

所以是一个字节序列

33 35 32 38 34 38 30 32 36 32 36 31 39 35 34

作为ASCII字符

我会像这样修改你的代码

dataIN.readFully(data); // always read 17 bytes, not less
String text = new String(data, 0, 2, 13); // decodes 8-bit bytes as a String
long number = Long.parseLong(text);

您看到的是需要解码为数字的ascii值的十六进制。作为十进制的字符“0”是48或十六进制0x30,“9”之前作为十进制的字符是57或十六进制的字符是0x39

所以是一个字节序列

33 35 32 38 34 38 30 32 36 32 36 31 39 35 34

作为ASCII字符

我会像这样修改你的代码

dataIN.readFully(data); // always read 17 bytes, not less
String text = new String(data, 0, 2, 13); // decodes 8-bit bytes as a String
long number = Long.parseLong(text);

也许我的toHex函数做得不对?我肯定会为该函数编写一些单元测试——它闻起来有点可疑,在Java中使用byte[]需要大量关注细节。或者替换为网络上可用的众多函数中的一个(这里有无数个答案:)也许我的toHex函数做得不对?我肯定会为该函数编写一些单元测试-它闻起来很可疑,在Java中使用byte[]需要大量的注意细节。或者替换为网络上可用的众多功能之一(这里有无数的答案:)我对传输数据的理解是正确的。我的问题是我在读取一个十六进制字符串,而没有将它转换成数字。@sergio,所以你对协议的理解是错误的。你期待一个数字,而你得到的是一个十六进制字符串。否则为什么要发帖?我对传输数据的理解是正确的。我的问题是我在读取一个十六进制字符串,而没有将它转换成数字。@sergio,所以你对协议的理解是错误的。你期待一个数字,而你得到的是一个十六进制字符串。否则为什么要发帖?