如何解析远程计算机名称以获取 java 中的 IP 地址

How to resolve a remote computer name to get it IP address in java

我正在尝试编写一个程序,将数据包从计算机 A 发送到计算机 B。两台计算机都必须有我的 java 程序的副本。这需要在 JTextField 对象中输入远程计算机的名称 B,在 JTextArea 对象中输入消息,然后单击发送按钮。

我的程序应该能够将给定的计算机名称解析为 IP 地址,以便将 IP 地址作为参数包含在我的 DatagramPacket 构造函数中。

我尝试使用以下方法进行解析,但我得到了 javax.naming.CommunicationException.

String clientname="user";
Hashtable<String,Object> env=new Hashtable<String,Object>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
        env.put(Context.PROVIDER_URL,"dns://www.google.com");
        DirContext con=new InitialDirContext(env);
       Object obj=con.lookup("clientname");

抛出异常

javax.naming.CommunicationException: DNS error [Root exception is java.net.SocketTimeoutException: Receive timed out]; remaining name 'user'
at com.sun.jndi.dns.DnsClient.query(DnsClient.java:300)
at com.sun.jndi.dns.Resolver.query(Resolver.java:81)
at com.sun.jndi.dns.DnsContext.c_lookup(DnsContext.java:286)
at com.sun.jndi.toolkit.ctx.ComponentContext.p_lookup(ComponentContext.java:544)
at com.sun.jndi.toolkit.ctx.PartialCompositeContext.lookup(PartialCompositeContext.java:177)
at com.sun.jndi.toolkit.ctx.PartialCompositeContext.lookup(PartialCompositeContext.java:166)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
Caused by: java.net.SocketTimeoutException: Receive timed out
at java.net.DualStackPlainDatagramSocketImpl.socketReceiveOrPeekData(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.receive0(DualStackPlainDatagramSocketImpl.java:121)
at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:145)
at java.net.DatagramSocket.receive(DatagramSocket.java:786)
at com.sun.jndi.dns.DnsClient.doUdpQuery(DnsClient.java:411)
at com.sun.jndi.dns.DnsClient.query(DnsClient.java:203)
... 7 more

问题

我怎样才能实现我的目标,因为在我看来 java DNS 服务提供商只能解析域名而不是单个计算机名称?我已经为此苦苦挣扎了3天。

感谢任何帮助。

你读过 http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/jndi-dns.html 了吗?

接缝像:

Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url",    "dns://google-public-dns-a.google.com");

DirContext ictx = new InitialDirContext(env);
Attributes attrs1 = ictx.getAttributes("clientname", new String[] {"A"});

就是你想要的。

超时值可配置为:

env.put("com.sun.jndi.dns.timeout.initial", "2000");

env.put("com.sun.jndi.dns.timeout.retries", "3");

如果您要使用 public DNS 服务器而不是异常中显示的 clientname,请使用 FQDN(完全限定域名)。 Google 希望对 clientname 一无所知 ;-).

使用 JNDI 仅在需要特定 DNS attributes/entries 时才有用。

也许以下更适合您:

final InetAddress inetAddress = InetAddress.getByName("clientname");
final String ipAddress = inetAddress.getHostAddress();

本地 DNS 基础设施 - 就像 OS 一样 - 将被使用,你不需要自己提供 DNS 服务器。

http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html

http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#getByName%28java.lang.String%29

Determines the IP address of a host, given the host's name.

The host name can either be a machine name, such as "java.sun.com", or a textual representation of its IP address. If a literal IP address is supplied, only the validity of the address format is checked.

For host specified in literal IPv6 address, either the form defined in RFC 2732 or the literal IPv6 address format defined in RFC 2373 is accepted. IPv6 scoped addresses are also supported.