首页 > 解决方案 > DatagramPacket 的 IP 字段何时从destinationIP 更改为sourceIP?

问题描述

我正在尝试为一个项目熟悉 java 中的 Datagram 系统,目前,我们只使用 UDP 包。

要发送消息,我们在 DatagramPacket 上设置目标 ip。

    /*
     * The fields of this class are package-private since
     * DatagramSocketImpl classes needs to access them.
     */
    byte[] buf;
    int offset;
    int length;
    int bufLength;
    InetAddress address;
    int port;

这样做,“地址”字段成为目标地址,但是当我们收到包裹时,该字段对应于源地址。

我认为对象本身不是通过网络发送的,但它的信息是。

我已经简要检查了 DatagramPacket 和 DatagramSocket 的源代码,但似乎没有找到任何“地址”字段被更改的实例。

我的猜测是 DatagramPacket 类只存储一个 IP,因为另一个是机器的,当通过网络发送消息时,UDP 包含两个 IP,然后由 DatagramSocket.receive() 处理并将丢失的数据报上的(源)地址。那是对的吗?

标签: javadatagram

解决方案


我认为对象本身不是通过网络发送的,但它的信息是。

明显地!

Java 对象仅存在于正在运行的 Java 程序的上下文中。在 JVM 之外它根本不存在。

因此,即使在不同的 Java 应用程序之间发送一个序列化对象,您也不是真正发送该对象。(您实际上是在发送对象状态的表示,可以反序列化以提供类似的对象。)


回到你的问题。当您发送数据报包时,您不是在发送DatagramPacket对象。这些DatagramPacket对象实际上是保存您正在发送的数据包或您刚刚收到的数据包的缓冲区。

在您的情况下,您在不同机器上的不同 JVM 中有两个不同的DatagramPacket对象,具有(可能)不同的 IP 地址。实际发生的是:

  • DatagramSocket::receive接收数据报时,将远程地址设置DatagramPacket为接收数据包的源IP;请参阅javadoc
  • DatagramSocket::send不设置远程地址DatagramPacket。相反,它使用它作为数据报的目的地;请参阅javadoc

推荐阅读