12

Java技巧: 根据网址/域名查询DNS/IP地址

 4 years ago
source link: https://renfufei.blog.csdn.net/article/details/78722127
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Java技巧: 根据网址/域名查询DNS/IP地址

铁锚 2017-12-05 16:48:58 4789

需求: 给定一个URL地址, 例如: http://www.cncounter.com/tools/shorturl.php, 解析对应的IP地址和端口号。

说明: 本文不涉及底层的 DNS 协议, 直接使用Java平台提供的API进行操作。

DNS也就是 Domain Name Service,即 域名服务。

我们知道, Java中与网址有关的类包括 java.net.URLjava.net.URI 等, 其中 URI 是资源定位符, 可能包括 file: 之类的协议。

所以此处我们使用 URL 类, 获取端口号的代码如下:

    /**
     * 获取端口号
     *
     * @param href 网址, ftp, http, nntp, ... 等等
     * @return
     * @throws IOException
     */
    public static int parsePort(String href) throws IOException {
        //
        URL url = new URL(href);
        // 端口号; 如果 href 中没有明确指定则为 -1
        int port = url.getPort();
        if (port < 0) {
            // 获取对应协议的默认端口号
            port = url.getDefaultPort();
        }
        return port;
    }

URL 类是Java早期就存在的一个类。 内部逻辑比较复杂, 有兴趣可以自己查看相关的JDK实现代码。

其中获取端口号的2个方法:

  • getPort() 就是获取网址里面指明的端口号, 如果没有指定, 则返回 -1
  • getDefaultPort() 是获取协议对应的默认端口号, 如 http 协议默认端口号为 80, https 协议默认端口号是 443 等。

然后我们看提取 Host 部分的代码:

    /**
     * 获取Host部分
     *
     * @param href 网址, ftp, http, nntp, ... 等等
     * @return
     * @throws IOException
     */
    public static String parseHost(String href) throws IOException {
        //
        URL url = new URL(href);
        // 获取 host 部分
        String host = url.getHost();
        return host;
    }

本质上, 也可以通过正则表达式或者String直接截取 Host, 但如果碰上复杂情况, 也不好处理, 例如: https://yourname:[email protected]/mumu-osc/NiceFish.git 这样的复杂网址。

提取出域名之后, 可以通过 java.net.InetAddress 类来查找IP地址。

代码如下所示:

    /**
     * 根据域名(host)解析IP地址
     *
     * @param host 域名
     * @return
     * @throws IOException
     */
    public static String parseIp(String host) throws IOException {
        // 根据域名查找IP地址
        InetAddress inetAddress = InetAddress.getByName(host);
        // IP 地址
        String address = inetAddress.getHostAddress();
        return address;
    }

可以看到,我们使用了 InetAddress.getByName() 静态方法来查找IP。

该类也提供了其他静态方法, 但一般不怎么使用, 有兴趣可以点开源码看看。

然后, 我们通过 main() 方法进行简单的测试:

    public static void main(String[] args) throws IOException {
        //
        String href = "http://www.cncounter.com/tools/shorturl.php";
        // 端口号
        int port = parsePort(href);
        // 域名
        String host = parseHost(href);
        // IP 地址
        String address = parseIp(host);
    //
        System.out.println("host=" + host); 
        System.out.println("port=" + port); 
        System.out.println("address=" + address); 
    }

执行结果为:

host=www.cncounter.com
port=80
address=198.11.179.83

知道IP和端口号, 我们就可以直接通过 Socket 来进行连接了。

当然, 如果是 http 协议, 可以使用 Apache 的 HttpClient 工具, 功能强大而且使用方便。 但这个库有个不好的地方在于,各个版本之间并不兼容, API 也经常换, 编程时需要根据特定版本号来进行处理。

完整的代码如下所示:


import java.io.IOException;
import java.net.*;

/**
 * 查找IP地址
 */
public class TestFindDNS {
    public static void main(String[] args) throws IOException {
        //
        String href = "http://www.cncounter.com/tools/shorturl.php";
        // 端口号
        int port = parsePort(href);
        // 域名
        String host = parseHost(href);
        // IP 地址
        String address = parseIp(host);
        //
        System.out.println("host=" + host);
        System.out.println("port=" + port);
        System.out.println("address=" + address);
    }

    /**
     * 获取端口号
     *
     * @param href 网址, ftp, http, nntp, ... 等等
     * @return
     * @throws IOException
     */
    public static int parsePort(String href) throws IOException {
        //
        URL url = new URL(href);
        // 端口号; 如果 href 中没有明确指定则为 -1
        int port = url.getPort();
        if (port < 0) {
            // 获取对应协议的默认端口号
            port = url.getDefaultPort();
        }
        return port;
    }

    /**
     * 获取Host部分
     *
     * @param href 网址, ftp, http, nntp, ... 等等
     * @return
     * @throws IOException
     */
    public static String parseHost(String href) throws IOException {
        //
        URL url = new URL(href);
        // 获取 host 部分
        String host = url.getHost();
        return host;
    }

    /**
     * 根据域名(host)解析IP地址
     *
     * @param host 域名
     * @return
     * @throws IOException
     */
    public static String parseIp(String host) throws IOException {
        // 根据域名查找IP地址
        InetAddress.getAllByName(host);
        InetAddress inetAddress = InetAddress.getByName(host);
        // IP 地址
        String address = inetAddress.getHostAddress();
        return address;
    }
}

OK, 请根据具体情况进行适当的封装和处理。

日期: 2017年12月05日

作者: 铁锚: http://blog.csdn.net/renfufei


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK