Vert.x 核心模块 DNS(十五)

时间:2022-06-01 20:02:00

DNS客户端

通常你会发现处在一个需要以异步方式获取DNS信息的状况。不幸的是,在JVM自身的API不可能做到。正因为此,Vert.x提供了自己完全异步的DNS解析。为了获取DnsClient实例,可以通过Vert.x实例进行创建。

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

注意,可传入InetSocketAddress多个参数,指定多个DNS服务器支持DNS解析。如果在解析时一旦产生错误,解析时将按照传入参数的顺序进行查询,。

 查找

为了查找一个给定域名的IPv4地址或ipv6地址。第一个返回的地址将会被使用。这与你使用操作系统nslookup命令类似。

为了查找“vertx.io”域名的IPv4或IPv6地址,可以象下面这样用:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.lookup("vertx.io", ar -> {

  if(ar.succeeded()) {

   System.out.println(ar.result());

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 查询IPV4直址(lookup4)

为了查找给定域名的IPV4地址,最先返回的将被使用,这与操作系统的”nslookup”命令相同,为了查找”vetx.io”域名的IPV4地址,可这样做:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.lookup4("vertx.io", ar -> {

  if(ar.succeeded()) {

   System.out.println(ar.result());

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 查询IPV6地址(lookup6)

为了查找给定域名的IPV6地址,最先返回的将被使用,这与操作系统的”nslookup”命令相同,为了查找”vetx.io”域名的IPV6地址,可这样做:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.lookup6("vertx.io", ar -> {

  if(ar.succeeded()) {

   System.out.println(ar.result());

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 解析IPV4地址

为了解析给定域名的有效IPV4地址。这与Unix操作系统中的”dig”命令类似。

为了找到 “Vertx.io”域名的所有ipv4地址,下面做是典型做法:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolveA("vertx.io", ar ->{

  if(ar.succeeded()) {

   List<String> records = ar.result();

    for(String record : records) {

     System.out.println(record);

    }

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 解析IPV6地址

为了解析给定域名的IPV6地址。这与Unix操作系统中的”dig”命令类似。

为了找到 “Vertx.io”域名的所有ipv6地址,下面做是典型做法:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolveAAAA("vertx.io", ar-> {

  if(ar.succeeded()) {

   List<String> records = ar.result();

    for(String record : records) {

     System.out.println(record);

    }

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 解析别名

为指定的名称解析所有的别名,这与unix操作系统中的”dig”命令类似。

为了找到 “Vertx.io”域名的所有别名,下面做是典型做法:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolveCNAME("vertx.io", ar-> {

  if(ar.succeeded()) {

   List<String> records = ar.result();

    for(String record : records) {

     System.out.println(record);

    }

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 解析邮件交换记录

试图解析给定域名的所有邮件交换记录。MX记录用于决定在给定的域命下,哪一个服务器用于接收邮件。

为了查找”vertx.io “所有的MX记录,典型做法所下:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolveMX("vertx.io", ar ->{

  if(ar.succeeded()) {

   List<MxRecord> records = ar.result();

    for(MxRecord record: records) {

     System.out.println(record);

    }

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

注意反回的MxRecord列表是根据优先级排序的,这意味着较小的优先级的MxRecord会出现在前面。MxRecord允许访问优先级和MX记录的名字。调用的方法如下:

record.priority();

record.name();

 解析说明

可以解析给定域名的所有TXT记录,TXT记录通常用于定义域名的其他信息。为了解析”vertx.io”的所有TXT记录,如下代码可以做到:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolveTXT("vertx.io", ar-> {

  if(ar.succeeded()) {

   List<String> records = ar.result();

    for(String record: records) {

     System.out.println(record);

    }

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 解析NS记录

为了解析给定域名的所有NS记录,NS记录指得是哪个DNS服务器控制指定域名的的NS信息。为了解析”vertx.io”的所有NS记录,如下代码可以做到:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolveNS("vertx.io", ar ->{

  if(ar.succeeded()) {

   List<String> records = ar.result();

    for(String record: records) {

     System.out.println(record);

    }

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 解析SRV(主机与服务的映射)记录

此方法(resolveSRV)是解析指定域名的所有SRV记录。SRV记录用于定义服务的额外信息,如端口,主机。一些协议需要此额名信息。为了获取“vertx.io”的所有SRV记录,典型做法如下:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolveSRV("vertx.io", ar-> {

  if(ar.succeeded()) {

   List<SrvRecord> records = ar.result();

    for(SrvRecord record: records) {

     System.out.println(record);

    }

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

小心返回的SrvRecord列表是根据优先级排序的,这表示较小优先级的SrvRecords会放在前面。SrvRecord允许访问包含在SRV中的所有信息。

record.priority();

record.name();

record.weight();

record.port();

record.protocol();

record.service();

record.target();

请参考API文档获取额外信息。

 解析PTR(resolvePTR)

为了解析指定名称的PTR记录。PTR映射地址到域名。为了解析IP地址10.0.0.1,需要使用PTR说明如”1.0.0.10.in-addr.arpa”。

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.resolvePTR("1.0.0.10.in-addr.arpa",ar -> {

  if(ar.succeeded()) {

   String record = ar.result();

   System.out.println(record);

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 反向查询

为ip地址进行反向查询。最基本的是解析PTR记录,但是reverseLookUp允许传入一个有效的IP地址而不是一个有效的PTR查询字符串。为了反向查询IP地址10.0.0.1,可以象下面一做:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.reverseLookup("10.0.0.1", ar-> {

  if(ar.succeeded()) {

   String record = ar.result();

   System.out.println(record);

  } else{

   System.out.println("Failed to resolve entry" + ar.cause());

  }

});

 错误处理

正如在前面小节所见,DnsClient可以传入一个处理器,在查询完成后将调用处理器获取AsyncResult。如得到一个DnsException错误,一个DnsResponseCode会指明失败的原因。这个DnsResponseCode用于说明更多的产生错误的原因。可能的DnsResponseCode如下:

·          NOERROR 查谒不到记录

·          FORMERROR格式错误

·          SERVFAIL服务器失败

·          NXDOMAIN域名错误

·          NOTIMPL 没有被域名实现

·          REFUSEDDNS服务器拒绝查询

·          YXDOMAIN域名不存在

·          YXRESET 资源记录不存在

·          NXRRSETRRSET不存在

·          NOTZONE 域名不在区域

·          BADVERS 针对版本的错误扩展机制

·          BADSIG 错误签名

·          BADKEY 错误的键

·          BADTIME 错误时间戳

这此错误都有DNS服务器自己产生。可以象下面这样DnsException中获取DnsResponseCode:

DnsClient client = vertx.createDnsClient(53,"10.0.0.1");

client.lookup("nonexisting.vert.xio",ar -> {

  if(ar.succeeded()) {

   String record = ar.result();

   System.out.println(record);

  } else{

   Throwable cause = ar.cause();

    if(cause instanceof DnsException) {

     DnsException exception = (DnsException) cause;

     DnsResponseCode code = exception.code();

      //...

    }else {

     System.out.println("Failed to resolve entry" + ar.cause());

    }

  }

});