酒诡 发表于 2023-10-21 22:45:54

[Java][网络程序开发]《DNS服务简单实现》


项目使用了Netty高性能网络通信框架。
使用了4.1.X版本
启动后,就可以使用该服务器作为DNS服务器。
public class Dns {

    public static void main(String[] args) {
      final NioEventLoopGroup group = new NioEventLoopGroup();
      try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group).channel(NioDatagramChannel.class)
                  .handler(new ChannelInitializer<NioDatagramChannel>() {
                        @Override
                        protected void initChannel(NioDatagramChannel nioDatagramChannel) throws Exception {
                            nioDatagramChannel.pipeline().addLast(new DatagramDnsQueryDecoder());
                            nioDatagramChannel.pipeline().addLast(new DatagramDnsResponseEncoder());
                            nioDatagramChannel.pipeline().addLast(new DnsHandler());
                        }
                  }).option(ChannelOption.SO_BROADCAST, true);

            ChannelFuture future = bootstrap.bind(53).sync();
            future.channel().closeFuture().sync();
      } catch (InterruptedException e) {
            e.printStackTrace();
      } finally {
            group.shutdownGracefully();
      }
    }
}

class DnsHandler extends SimpleChannelInboundHandler<DatagramDnsQuery> {
    @Override
    public void channelRead0(ChannelHandlerContext ctx, DatagramDnsQuery query) throws UnsupportedEncodingException {
      // 假数据,域名和ip的对应关系应该放到数据库中
      Map<String, byte[]> ipMap = new HashMap<>();
      ipMap.put("www.cnhongker.net.", new byte[] { 74, 121, (byte) 149, (byte)218 });
      DatagramDnsResponse response = new DatagramDnsResponse(query.recipient(), query.sender(), query.id());
      try {
            DefaultDnsQuestion dnsQuestion = query.recordAt(DnsSection.QUESTION);
            response.addRecord(DnsSection.QUESTION, dnsQuestion);
            System.out.println("查询的域名:" + dnsQuestion.name());

            ByteBuf buf = null;
            if (ipMap.containsKey(dnsQuestion.name())) {
                buf = Unpooled.wrappedBuffer(ipMap.get(dnsQuestion.name()));
            } else {
                // TODO对于没有的域名采用迭代方式
                // buf = Unpooled.wrappedBuffer(new byte[] { 127, 0, 0, 1});
            }
            // TTL设置为10s, 如果短时间内多次请求,客户端会使用本地缓存
            DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord(dnsQuestion.name(), DnsRecordType.A, 10, buf);
            response.addRecord(DnsSection.ANSWER, queryAnswer);

      } catch (Exception e) {
            System.out.println("异常了:" + e);
      }finally {
            ctx.writeAndFlush(response);
      }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
      cause.printStackTrace();
    }
}
页: [1]
查看完整版本: [Java][网络程序开发]《DNS服务简单实现》