如何从Java中获取网络数据包数据

chr*_*her 5 c java networking udp packet

在C中如果你有一个特定类型的数据包,你通常做的是定义一些结构并将char*转换为指向结构的指针.在此之后,您可以直接以编程方式访问网络数据包中的所有数据字段.像这样:

struct rdp_header {
  int version;
  char serverId[20];
};
Run Code Online (Sandbox Code Playgroud)

获得网络数据包后,您可以快速执行以下操作:

char * packet;
// receive packet
rdp_header * pckt = (rdp_header * packet);
printf("Servername : %20.20s\n", pckt.serverId);
Run Code Online (Sandbox Code Playgroud)

这种技术对基于UDP的协议非常有用,并且允许使用非常少的代码进行非常快速和非常有效的数据包解析和发送,以及简单的错误处理(只需检查数据包的长度).在java中有同样的,同样快速的方法吗?或者你被迫使用基于流的技术?

Aln*_*tak 3

将数据包读入字节数组,然后从中提取所需的位和字节。

这是一个示例,没有异常处理:

DatagramSocket s = new DatagramSocket(port);
DatagramPacket p;
byte buffer[] = new byte[4096];

while (true) {
    p = new DatagramPacket(buffer, buffer.length);
    s.receive(p);

    // your packet is now in buffer[];
    int version = buffer[0] << 24 + buffer[1] << 16 + buffer[2] < 8 + buffer[3];
    byte[] serverId = new byte[20];
    System.arraycopy(buffer, 4, serverId, 0, 20);

     // and process the rest
}
Run Code Online (Sandbox Code Playgroud)

在实践中,您可能最终会使用辅助函数来从字节数组中按网络顺序提取数据字段,或者正如Tom在评论中指出的那样,您可以使用 a ByteArrayInputStream(),从中您可以构造一个DataInputStream()具有读取结构化数据的方法的来自流:

...

while (true) {
    p = new DatagramPacket(buffer, buffer.length);
    s.receive(p);

    ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
    DataInput di = new DataInputStream(bais);

    int version = di.readInt();
    byte[] serverId = new byte[20];
    di.readFully(serverId);
    ...
}
Run Code Online (Sandbox Code Playgroud)