1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.example.dns.tcp;
17
18 import io.netty5.bootstrap.Bootstrap;
19 import io.netty5.buffer.BufferUtil;
20 import io.netty5.channel.Channel;
21 import io.netty5.channel.ChannelHandlerContext;
22 import io.netty5.channel.ChannelInitializer;
23 import io.netty5.channel.ChannelPipeline;
24 import io.netty5.channel.EventLoopGroup;
25 import io.netty5.channel.MultithreadEventLoopGroup;
26 import io.netty5.channel.SimpleChannelInboundHandler;
27 import io.netty5.channel.nio.NioHandler;
28 import io.netty5.channel.socket.SocketChannel;
29 import io.netty5.channel.socket.nio.NioSocketChannel;
30 import io.netty5.handler.codec.dns.DefaultDnsQuery;
31 import io.netty5.handler.codec.dns.DefaultDnsQuestion;
32 import io.netty5.handler.codec.dns.DefaultDnsResponse;
33 import io.netty5.handler.codec.dns.DnsOpCode;
34 import io.netty5.handler.codec.dns.DnsQuery;
35 import io.netty5.handler.codec.dns.DnsQuestion;
36 import io.netty5.handler.codec.dns.DnsRawRecord;
37 import io.netty5.handler.codec.dns.DnsRecord;
38 import io.netty5.handler.codec.dns.DnsRecordType;
39 import io.netty5.handler.codec.dns.DnsSection;
40 import io.netty5.handler.codec.dns.TcpDnsQueryEncoder;
41 import io.netty5.handler.codec.dns.TcpDnsResponseDecoder;
42 import io.netty5.util.NetUtil;
43
44 import java.util.Random;
45 import java.util.concurrent.TimeUnit;
46
47 public final class TcpDnsClient {
48 private static final String QUERY_DOMAIN = "www.example.com";
49 private static final int DNS_SERVER_PORT = 53;
50 private static final String DNS_SERVER_HOST = "8.8.8.8";
51
52 private TcpDnsClient() {
53 }
54
55 private static void handleQueryResp(DefaultDnsResponse msg) {
56 if (msg.count(DnsSection.QUESTION) > 0) {
57 DnsQuestion question = msg.recordAt(DnsSection.QUESTION, 0);
58 System.out.printf("name: %s%n", question.name());
59 }
60 for (int i = 0, count = msg.count(DnsSection.ANSWER); i < count; i++) {
61 DnsRecord record = msg.recordAt(DnsSection.ANSWER, i);
62 if (record.type() == DnsRecordType.A) {
63
64 DnsRawRecord raw = (DnsRawRecord) record;
65 System.out.println(NetUtil.bytesToIpAddress(BufferUtil.getBytes(raw.content())));
66 }
67 }
68 }
69
70 public static void main(String[] args) throws Exception {
71 EventLoopGroup group = new MultithreadEventLoopGroup(NioHandler.newFactory());
72 try {
73 Bootstrap b = new Bootstrap();
74 b.group(group)
75 .channel(NioSocketChannel.class)
76 .handler(new ChannelInitializer<SocketChannel>() {
77 @Override
78 protected void initChannel(SocketChannel ch) {
79 ChannelPipeline p = ch.pipeline();
80 p.addLast(new TcpDnsQueryEncoder())
81 .addLast(new TcpDnsResponseDecoder())
82 .addLast(new SimpleChannelInboundHandler<DefaultDnsResponse>() {
83 @Override
84 protected void messageReceived(
85 ChannelHandlerContext ctx, DefaultDnsResponse msg) {
86 try {
87 handleQueryResp(msg);
88 } finally {
89 ctx.close();
90 }
91 }
92 });
93 }
94 });
95
96 final Channel ch = b.connect(DNS_SERVER_HOST, DNS_SERVER_PORT).asStage().get();
97
98 int randomID = new Random().nextInt(60000 - 1000) + 1000;
99 DnsQuery query = new DefaultDnsQuery(randomID, DnsOpCode.QUERY)
100 .setRecord(DnsSection.QUESTION, new DefaultDnsQuestion(QUERY_DOMAIN, DnsRecordType.A));
101 ch.writeAndFlush(query).asStage().sync();
102 boolean success = ch.closeFuture().asStage().await(10, TimeUnit.SECONDS);
103 if (!success) {
104 System.err.println("dns query timeout!");
105 ch.close().asStage().sync();
106 }
107 } finally {
108 group.shutdownGracefully();
109 }
110 }
111 }