[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]