尝试ping和获取DNS域的记录时,我遇到了无法解释的错误。

huangapple go评论86阅读模式
英文:

When trying to ping and get records of dns domain, I get unexplained error

问题

我对golang非常陌生,我正在使用来自github.com/miekg/dns的dns库进行操作。我只是在尝试使用这个库。我首先在一个循环中调用google.com,循环调用该域名10次,然后计算这10次的平均响应时间。在这个过程中,我将客户端IP设置为本地主机的53端口。

然而,当我在循环外部执行相同的操作时,将客户端IP设置为相同的本地主机的53端口时,它会报错"connection refused"。当我将客户端IP设置为192.168.1.21时(与本地主机相同),也会出现相同的错误。然而,当我将客户端IP设置为192.168.1.32时(我的树莓派在网络上的IP),它可以正常工作!为什么它能够在循环中建立DNS连接,但在循环外部无法建立连接?为什么它能够在循环外部使用与运行脚本的设备不同的IP建立连接?以下是我的代码:

package main

import (
	"fmt"
	"github.com/miekg/dns"
	"math"
)

func main() {
	m := new(dns.Msg)
	m.SetQuestion(dns.Fqdn("google.com"), dns.TypeA)

	c := new(dns.Client)
	var individualPings float64

	//循环10次,打印每次的结果,并将结果累加到individualPings变量中,以便在最后计算平均值
	for i := 1; i <= 10; i++ {
		_, rtt, _ := c.Exchange(m, "localhost:53")
		fmt.Printf("%vth ping is %v\n", i, rtt)
		individualPings = individualPings + (float64(rtt))
	}

	pingAverage := individualPings / 10
	fmt.Print("\nThe ping average was: ", math.Round(pingAverage)/1000, "ms\n")

	//尝试执行相同的操作
	_, rtt, err := c.Exchange(m, "localhost:53")
	if err != nil {
		panic(err)
	}
	print(rtt)

	//尝试执行相同的操作,但是客户端的IP地址是定义为ipv4而不是"localhost"
	in, rtt, err := c.Exchange(m, "192.168.1.21:53")
	if err != nil {
		panic(err)
	}
	fmt.Println(in.Answer)
	fmt.Println(rtt, "\n\n")

	//尝试执行相同的操作,但是客户端的IP地址是我的树莓派而不是运行脚本的设备。这个可以正常工作。当然,在达到这部分代码之前,程序会发生panic,但是我已经测试过它,去掉上面的杂乱代码后它可以正常工作。
	in, rtt, err = c.Exchange(m, "192.168.1.32:53")
	if err != nil {
		panic(err)
	}
	for record := range in.Answer {
		fmt.Println(in.Answer[record])
		fmt.Print("\t", rtt)
	}
}

谢谢 尝试ping和获取DNS域的记录时,我遇到了无法解释的错误。

英文:

I am very new to golang, and I am using the dns library from github.com/miekg/dns to do this. I'm just trying the library out. I first call upon google.com in a loop which calls the domain 10 times, then averages the 10 pings. It does this with the defined client IP being localhost on port 53.

When I do this out of the loop however, with my client IP being the same localhost on port 53, it gives the error of "connection refused". Same thing happens when I set my client IP to be 192.168.1.21, which has the same value of localhost. HOWEVER, when I set my client IP to be 192.168.1.32, which is the IP of my raspberry pi on my network, it works! How come it is able to make the DNS connection in that loop, but not outside the loop? How come it is able to make the connection outside the loop with a IP different from the device I am running the script on? Here is my code:

package main
import (
&quot;fmt&quot;
&quot;github.com/miekg/dns&quot;
&quot;math&quot;
)
func main() {
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn(&quot;google.com&quot;), dns.TypeA)
c := new(dns.Client)
var individualPings float64
//looping over for 10 times and prints each one while also adding it to variable individualPings to get average at the end
for i := 1; i &lt;= 10; i++ {
_, rtt, _ := c.Exchange(m, &quot;localhost:53&quot;)
fmt.Printf(&quot;%vth ping is %v\n&quot;, i, rtt)
individualPings = individualPings + (float64(rtt))
}
pingAverage := individualPings / 10
fmt.Print(&quot;\nThe ping average was: &quot;, math.Round(pingAverage)/1000, &quot;ms\n&quot;)
//tries to do the same thing
_, rtt, err := c.Exchange(m, &quot;localhost:53&quot;)
if err != nil {
panic(err)
}
print(rtt)
//tries to do the same thing but client is defined with it&#39;s ipv4 instead of just &quot;localhost&quot;
in, rtt, err := c.Exchange(m, &quot;192.168.1.21:53&quot;)
if err != nil {
panic(err)
}
fmt.Println(in.Answer)
fmt.Println(rtt, &quot;\n\n&quot;)
//tries to do the same thing but client is defined to be my raspberry pi instead of the device the script is running on. This works. Of course the program panics before it reaches this part, however I&#39;ve tested it without the clutter above and it works
in, rtt, err = c.Exchange(m, &quot;192.168.1.32:53&quot;)
if err != nil {
panic(err)
}
for record := range in.Answer {
fmt.Println(in.Answer[record])
fmt.Print(&quot;\t&quot;, rtt)
}
}

Thanks 尝试ping和获取DNS域的记录时,我遇到了无法解释的错误。

======================================

答案1

得分: 2

首先,要在特定的IP和端口上进行DNS查询,需要确保有一个DNS服务器在那里运行并响应查询。不能保证在localhost:53192.168.1.21:53上有这样的DNS服务器。因此,在询问为什么程序出错之前,首先使用像dig这样的工具检查是否实际上从特定的ip:port获取到DNS服务器的响应。

我首先在一个循环中调用google.com,该循环调用该域名10次,然后对这10次的ping时间取平均值。在这个过程中,定义的客户端IP是localhost,端口是53。
但是,当我在循环之外这样做时,客户端IP仍然是相同的localhost,端口是53,它会报错"connection refused"。

很可能在循环内部也会出现相同的错误。只是,在循环内部你没有处理错误,因此没有报告任何错误。比较一下循环内部的代码(没有错误处理):

_, rtt, _ := c.Exchange(m, "localhost:53")

和循环外部的代码(有错误处理):

_, rtt, err := c.Exchange(m, "localhost:53")
if err != nil {
panic(err)
}
英文:

First, in order to do a DNS query on a specific IP and port there need to be actually a DNS server running there and responding to queries. There is no guarantee that such a DNS server is on localhost:53 or 192.168.1.21:53. So first check with tools like dig that you actually do get a response from a DNS server at a specific ip:port in the first place before asking why you get errors in your program.

> I first call upon google.com in a loop which calls the domain 10 times, then averages the 10 pings. It does this with the defined client IP being localhost on port 53.<br>
> When I do this out of the loop however, with my client IP being the same localhost on port 53, it gives the error of "connection refused".

It likely gives the same error inside the loop. Only, inside the loop you simply don't handle the error and thus nothing gets reported. Compare your code inside the loop (no error handling):

    _, rtt, _ := c.Exchange(m, &quot;localhost:53&quot;)

with the code outside the loop (with error handling)

_, rtt, err := c.Exchange(m, &quot;localhost:53&quot;)
if err != nil {
panic(err)
}

huangapple
  • 本文由 发表于 2023年3月19日 14:11:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75780365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定