forked from hantmac/Mastering_Go_ZH_CN
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# **实现DNS查询** | ||
|
||
DNS全称**Domain Name System(域名系统)**,它的作用是将IP地址转换为类似```packt.com```的域名,或者将域名转换为IP地址。本节中开发的```DNS.go```程序的处理逻辑非常简单:如果程序执行时的命令行参数是一个有效的IP地址,则程序将查询该IP地址对应的主机名;其他情况下,程序将假定它处理的是一个主机名,并将其转换成一个或多个IP地址。 | ||
|
||
程序```DNS.go```的代码将分三部分介绍。第一部分程序包含以下Go代码: | ||
|
||
> ```go | ||
> package main | ||
> | ||
> import ( | ||
> "fmt" | ||
> "net" | ||
> "os" | ||
> ) | ||
> | ||
> func lookIP(address string) ([]string, error) { | ||
> hosts, err := net.LookupAddr(address) | ||
> if err != nil { | ||
> return nil, err | ||
> } | ||
> return hosts, nil | ||
> } | ||
> | ||
> func lookHostname(hostname string) ([]string, error) { | ||
> IPs, err := net.LookupHost(hostname) | ||
> if err != nil { | ||
> return nil, err | ||
> } | ||
> return IPs, nil | ||
> } | ||
> ``` | ||
函数```lookIP()```将一个IP地址作为输入,然后返回与该IP地址匹配的主机列表,这个功能通过函数```net.LookupAddr()```的帮助来实现。 | ||
而函数```lookHostname()```将主机名作为输入,使用```net.LookupHost()```函数进行处理,返回一个相关IP地址的列表。 | ||
程序```DNS.go```的第二部分是以下Go代码: | ||
> ```go | ||
> func main() { | ||
> arguments := os.Args | ||
> if len(arguments) == 1 { | ||
> fmt.Println("Please provide an argument!") | ||
> return | ||
> } | ||
> | ||
> input := arguments[1] | ||
> IPaddress := net.ParseIP(input) | ||
> ``` | ||
函数```net.ParseIP()```可以将输入字符串解析为IPv4或IPv6地址。如果输入一个非法的IP地址,函数```net.ParseIP()```将返回```nil```。 | ||
程序```DNS.go```的剩余Go代码如下: | ||
> ```go | ||
> if IPaddress == nil { | ||
> IPs, err := lookHostname(input) | ||
> if err == nil { | ||
> for _, singleIP := range IPs { | ||
> fmt.Println(singleIP) | ||
> } | ||
> } | ||
> } else { | ||
> hosts, err := lookIP(input) | ||
> if err == nil { | ||
> for _, hostname := range hosts { | ||
> fmt.Println(hostname) | ||
> } | ||
> } | ||
> } | ||
> } | ||
> ``` | ||
执行```DNS.go```程序,并携带不同的输入参数,将生成以下输出: | ||
> ```shell | ||
> $ go run DNS.go 127.0.0.1 | ||
> localhost | ||
> $ go run DNS.go 192.168.1.1 | ||
> cisco | ||
> $ go run DNS.go packtpub.com | ||
> 83.166.169.231 | ||
> $ go run DNS.go google.com | ||
> 2a00:1450:4001:816::200e | ||
> 216.58.210.14 | ||
> $ go run DNS.go www.google.com | ||
> 2a00:1450:4001:816::2004 | ||
> 216.58.214.36 | ||
> $ go run DNS.go cnn.com | ||
> 2a04:4e42::323 | ||
> 2a04:4e42:600::323 | ||
> 2a04:4e42:400::323 | ||
> 2a04:4e42:200::323 | ||
> 151.101.193.67 | ||
> 151.101.1.67 | ||
> 151.101.129.67 | ||
> 151.101.65.67 | ||
> ``` | ||
可以看到```go run DNS.go 192.168.1.1```命令的输出来自```/etc/hosts```文件,因为在```/etc/hosts```文件中配置了IP地址```192.168.1.1```的别名```cisco```。 | ||
最后一个命令的输出演示了域名(```cnn.com```)可能有多个公网IP地址映射。请特别注意*公网*这个词,尽管```www.google.com```有多个IP地址,但是只有地址(```216.58.214.36```)是公网IP地址。 | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"os" | ||
) | ||
|
||
func lookIP(address string) ([]string, error) { | ||
hosts, err := net.LookupAddr(address) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return hosts, nil | ||
} | ||
|
||
func lookHostname(hostname string) ([]string, error) { | ||
IPs, err := net.LookupHost(hostname) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return IPs, nil | ||
} | ||
|
||
func main() { | ||
arguments := os.Args | ||
if len(arguments) == 1 { | ||
fmt.Println("Please provide an argument!") | ||
return | ||
} | ||
|
||
input := arguments[1] | ||
IPaddress := net.ParseIP(input) | ||
if IPaddress == nil { | ||
IPs, err := lookHostname(input) | ||
if err == nil { | ||
for _, singleIP := range IPs { | ||
fmt.Println(singleIP) | ||
} | ||
} | ||
} else { | ||
hosts, err := lookIP(input) | ||
if err == nil { | ||
for _, hostname := range hosts { | ||
fmt.Println(hostname) | ||
} | ||
} | ||
} | ||
} |