DNS解析查询
我们都知道DNS的概念,DNS允许使用域名代替难记的IP来标识主机,客户端可以使用DNS协议将域名解析为IP地址,这样我们就能通过域名访问服务端了。前面我们经常使用net.Dial()函数来向目标主机发送数据,它也支持传入域名,当我们传域名时,在代码底层实际上就发生了DNS解析将域名解析为了IP地址。实际上,我们也可以调用net包中的相关函数直接实现DNS解析步骤,这篇笔记我们学习Go语言net包中和DNS协议相关的内容。
解析域名记录
net.LookupHost()函数可以解析域名为IP地址(即获取DNS的A记录和AAAA记录),返回结果为字符串数组,它同时支持IPv4和IPv6。
package main
import (
"fmt"
"log/slog"
"net"
)
func main() {
addrs, err := net.LookupHost("www.google.com")
if err != nil {
slog.Error(err.Error())
return
}
for _, addr := range addrs {
fmt.Println(addr)
}
}
代码输出如下:
2404:6800:4004:825::2004
142.250.196.132
可以看到输出结果是谷歌www.google.com的IPv4和IPv6地址。
除了net.LookupHost()函数,我们还可以使用net.LookupIP()函数解析域名,它们的作用是类似的,只不过net.LookupIP()函数返回的是net.IP类型。
自定义DNS服务器
Go语言的DNS解析功能还支持自定义DNS服务器,下面例子中我们设置DNS服务器为Cloudflare的公共DNS服务1.1.1.1并基于该DNS服务器解析域名。
package main
import (
"context"
"fmt"
"log/slog"
"net"
"time"
)
func main() {
resolver := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Second * 5,
}
return d.DialContext(ctx, "udp", "1.1.1.1:53")
},
}
addrs, err := resolver.LookupHost(context.Background(), "www.google.com")
if err != nil {
slog.Error(err.Error())
return
}
for _, addr := range addrs {
fmt.Println(addr)
}
}
注:这里resolver.LookupHost()需要额外传一个上下文对象,我们使用context.Background()生成了一个空上下文传入。
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。