如何在Java中获取DatagramSocket(UDP)的本地地址

时间:2015-09-01 08:52:54

标签: java dns udp

我正在用Java实现一个带有DatagramSocket(UDP)的DNS服务器,代码如下:

try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
    DatagramPacket request = ... // Init Packet
    socket.receive(request);
    ... // Parse request, Resolve, then Generate reesponse
    socket.send(response);
}

它在我的PC和大多数服务器(包括aws,linode等)上运行良好,但在具有双以太网适配器的服务器上运行不正常。

此服务器具有网络配置:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.204
netmask 255.255.255.0

auto eth1
iface eth1 inet static
address 192.168.1.207
netmask 255.255.255.0

当我测试此DNS时,我得到:

# nslookup
> server 192.168.1.207
Default server: 192.168.1.207
Address: 192.168.1.207#53
> info.dev.
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; connection timed out; no servers could be reached
>

它似乎从eth1(192.168.1.207)收到一个数据包,但发送到eth0(192.168.1.204)。我的代码不知道收到数据包的接口。

try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
    ...
    socket.receive(request); // local socket address not known :-(
    ...
    socket.send(response); // local socket address not known :-(
}

套接字(TCP)可以做到这一点,但我不知道DatagramSocket(UDP)是否可以这样做。

UPDATE-1:

绑定一个接口而不是0.0.0.0,它工作正常。

UPDATE-2:

套接字(TCP)可以获取本地和远程地址:

try (ServerSocket server = new ServerSocket(23)) {
    try (Socket socket = server.accept()) {
        System.out.println(socket.getLocalSocketAddress());
        System.out.println(socket.getRemoteSocketAddress());
    }
}

1 个答案:

答案 0 :(得分:3)

该DatagramSocket的本地地址是0.0.0.0:53。你构造它时指定的那个。它用于回复的接口由静态IP路由表决定。不是这个代码。获取DatagramSocket的本地地址,甚至是数据报的目标地址(你可以用C而不是Java获得),如果有问题,将无法帮助你解决这个问题。

  

我的代码不知道收到数据包的接口。

正确。它并不关心。它正在监听所有IP地址。你告诉它这样做。它只关心远程地址,你没有显示,但显然是正确的。

try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {

我不知道你为什么两次发布这个帖子。

这里有一个静态IP路由问题。不是编程问题。