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

发布于 2024-11-19 15:07:31 字数 1681 浏览 1 评论 0原文

我正在致力于解码某个 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();
    }
}

输出:

-PARSER()--

-INITSESSION-- 侦听端口:1954

总数据包大小:17

ACK 数据包:000F

数据包:333532383438303236323631393534

完整数据包:000F333532383438303236323631393534

------CLOSESESSION------------

现在,我的问题:

这里发生的是设备发送 [0x00][0x0F]xxxxxxxxxxxxxxx 其中 xxxxxxx 是其 IMEI(数据包)。 我的问题是数据包上有太多 3,因此真正有效的输出是

352848026261954

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

Am working on decoding a protocol used by a certain gps device to communicate.
Right now, am analyzing the first data packet that it sends. I am able to read it, but am thinking am not reading it properly.

Here is what i got so far:

    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();
    }
}

the output:

-PARSER()--

-INITSESSION--
Listening on port :1954

Total packet size: 17

ACK PACKET : 000F

DATA PACKET: 333532383438303236323631393534

FULL PACKET: 000F333532383438303236323631393534

------CLOSESESSION------------

Now, my problem:

what is happening here is that the device sends a [0x00][0x0F]xxxxxxxxxxxxxxx
where the xxxxxxx is its imei (the data packet).
My problem is that there are way too many 3´s on the data packet, so the real valid output is

352848026261954

which you obtain by removing 3´s. my question is: can this behavior come from my code or its part of the protocol? i can correct this programmatically but am wanting to know it there is a way that code can cause these extra 3s.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愁以何悠 2024-11-26 15:07:31

您正在查看需要解码为数字的 ascii 值的十六进制。字符“0”十进制表示为 48 或十六进制表示为 0x30,字符“9”表示十进制表示为 57 或十六进制表示为 0x39。

所以字节序列

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

就是

"352848026261954"

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);

You are looking at the hex of the ascii values which needs to be decoded as numbers. The character '0' as a decimal is 48 or as hex 0x30, up to '9' is 57 as a decimal or 0x39 as hex.

So a sequence of bytes

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

is

"352848026261954"

as ASCII characters.

I would change your code like this

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);
眼泪也成诗 2024-11-26 15:07:31

这是 ASCII 数字编码。 0 被传输为“0”,即 0x30。 1 作为 0x31 传输。等等 所以你对数据格式的理解是不正确的。

This is ASCII numeric encoding. 0 is being transmitted as '0', which is 0x30. 1 is being transmitted as 0x31. Etc. So your understanding of the data format is incorrect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文