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

简介: 需求: 给定一个URL地址, 例如: http://www.cncounter.com/tools/shorturl.php, 解析对应的IP地址和端口号。 说明: 本文不涉及底层的 DNS 协议, 直接使用Java平台提供的API进行操作。

需求: 给定一个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:passwd@gitee.com/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

目录
相关文章
|
4月前
|
Java Apache 开发者
解决java.lang.IllegalArgumentException: Invalid uri由无效查询引起的问题
最后,当你修改代码以避免这个异常时,保持代码的整洁和可读性同样重要。注释你的代码,用意图清晰的方法名,并确保逻辑简单明了,这样在未来你或其他开发者需要时可以轻松地维护它。
515 20
|
6月前
|
存储 网络协议 Java
Java获取客户端IP问题:返回127.0.0.1
总结:要解决Java获取客户端IP返回127.0.0.1的问题,首先要找出原因,再采取合适的解决方案。请参考上述方案来改进代码,确保在各种网络环境下都能正确获取客户端IP地址。希望本文对您有所帮助。
445 25
|
6月前
|
搜索推荐 Java 定位技术
Java实现利用GeoLite2-City.mmdb根据IP定位城市的方法
在城市,国家,地区等地理位置数据获取之后,你可以依指定的业务需求,来进行进一步的数据处理。例如,你可以设计一个应用,根据用户的 IP 地址来个性化地展示内容,或者用于分析网络请求的来源等。
1175 20
|
5月前
|
SQL Java 数据库
解决Java Spring Boot应用中MyBatis-Plus查询问题的策略。
保持技能更新是侦探的重要素质。定期回顾最佳实践和新技术。比如,定期查看MyBatis-Plus的更新和社区的最佳做法,这样才能不断提升查询效率和性能。
218 1
|
8月前
|
监控 负载均衡 安全
静态IP代理与动态IP代理:提升速度与保障隐私的技术解析
本文探讨了静态IP代理和动态IP代理的特性和应用场景。静态IP代理通过高质量服务提供商、网络设置优化、定期更换IP与负载均衡及性能监控提升网络访问速度;动态IP代理则通过隐藏真实IP、增强安全性、绕过封锁和提供独立IP保障用户隐私。结合实际案例与代码示例,展示了两者在不同场景下的优势,帮助用户根据需求选择合适的代理服务以实现高效、安全的网络访问。
276 1
|
10月前
|
SQL NoSQL Java
Java使用sql查询mongodb
通过MongoDB Atlas Data Lake或Apache Drill,可以在Java中使用SQL语法查询MongoDB数据。这两种方法都需要适当的配置和依赖库的支持。希望本文提供的示例和说明能够帮助开发者实现这一目标。
393 17
|
10月前
|
网络协议 Unix Linux
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
434 11
|
10月前
|
SQL Java 数据库连接
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
1038 6
|
10月前
|
存储 运维 负载均衡
Hologres 查询队列全面解析
Hologres V3.0引入查询队列功能,实现请求有序处理、负载均衡和资源管理,特别适用于高并发场景。该功能通过智能分类和调度,确保复杂查询不会垄断资源,保障系统稳定性和响应效率。在电商等实时业务中,查询队列优化了数据写入和查询处理,支持高效批量任务,并具备自动流控、隔离与熔断机制,确保核心业务不受干扰,提升整体性能。
268 11
|
11月前
|
SQL NoSQL Java
Java使用sql查询mongodb
通过使用 MongoDB Connector for BI 和 JDBC,开发者可以在 Java 中使用 SQL 语法查询 MongoDB 数据库。这种方法对于熟悉 SQL 的团队非常有帮助,能够快速实现对 MongoDB 数据的操作。同时,也需要注意到这种方法的性能和功能限制,根据具体应用场景进行选择和优化。
425 9

相关产品

  • 云解析DNS
  • 推荐镜像

    更多
  • DNS