gpt4 book ai didi

go - 在 Go 中发送多个请求时出现零星的 EOF 错误

转载 作者:IT王子 更新时间:2023-10-29 02:23:09 26 4
gpt4 key购买 nike

首先让我说我是 Go 的新手,欢迎任何指点/更正。

我正在尝试编写一个小型 Go 应用程序,它将创建多个 DNS 查询并在各自的 Go 例程中发送它们。我从包含 1000 个 URL 的文件中获取 URL 并创建一个 slice ,对于 slice 中的每个 URL,我查询 A 记录,如果成功,则将 URL 和耗时推送到结果 channel ,如果 a 出现错误各自的错误 channel 。然后我会选择收听。

我正在努力解决的问题是,在使用 TCP 时我会收到(看似随机的)一些查询的 EOF 错误,而在使用 UDP 时会收到 i/o 超时错误。我想使用 TCP 并确保响应,我不知道为什么会收到 EOF 错误。如果我对同一个 URL 和 1000 个不同的 URL 进行 1000 次查询,也会发生这种情况

在 OSX 和 Go 1.6 版上工作

这是我目前所拥有的:

package main

import (
"bufio"
"fmt"
"github.com/miekg/dns"
"os"
"time"
)

// CHECK AND PRINT ERRORS
func checkErr(e error) {
if e != nil {
fmt.Println("Error: %s", e)
}
}

// MAKES A SLICE OF URLS FROM TXT FILE
func urlSlice() []string {
result := []string{}
file, err := os.Open("topsites.txt")
checkErr(err)
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
result = append(result, scanner.Text())
}
return result
}

func makeQuery(target string) (string, error) {
server := "8.8.8.8"
// WILL RECIEVE EOF ERROR IF TCP - I/O TIMEOUT IF UDP
c := dns.Client{Net: "tcp", Timeout: time.Duration(100 * time.Second)}
m := dns.Msg{}
m.SetQuestion(dns.Fqdn(target+"."), dns.TypeA)

_, t, err := c.Exchange(&m, server+":53")
if err != nil {
return "", err
}
return "Url: " + target + " - - Took: " + t.String(), nil
}

func main() {
start := time.Now()
targets := urlSlice()
resch, errch := make(chan string), make(chan error)
for _, url := range targets {
go func(url string) {
res, err := makeQuery(url)
if err != nil {
errch <- err
return
}
resch <- res
}(url)
}

for i := 0; i < len(targets); i++ {
select {
case res := <-resch:
fmt.Println(res)
case err := <-errch:
fmt.Println(err)
}
}
elapsed := time.Since(start)
fmt.Println("\ntotal time elapsed: ", elapsed)
}

输出:

Url: facebook.com - - Took: 548.582107ms
Url: wordpress.com - - Took: 548.805505ms
Url: google.com.br - - Took: 541.491363ms
Url: onclickads.net - - Took: 548.16544ms
Url: bongacams.com - - Took: 543.28688ms
Url: tianya.cn - - Took: 543.41525ms
Url: blogger.com - - Took: 544.461005ms
Url: alibaba.com - - Took: 543.53541ms
Url: gmw.cn - - Took: 543.56093ms
Url: pornhub.com - - Took: 664.297282ms
Url: outbrain.com - - Took: 664.423217ms
Url: ask.com - - Took: 671.557037ms
EOF
EOF
EOF
EOF
EOF
EOF
EOF
Url: t.co - - Took: 1.166130918s
Url: youth.cn - - Took: 1.946658912s
Url: apple.com - - Took: 2.763568935s

...continued...

total time elapsed: 23.703546858s

所有的想法、建议和帮助都值得赞赏。谢谢!

最佳答案

这可能是有趣的:https://idea.popcount.org/2013-11-28-how-to-resolve-a-million-domains/

根据这篇文章,天真的方法受限于可以同时打开多少 UDP 套接字 - 大约 1000。我假设 TCP 套接字也是如此 - 你将用完文件描述符或一些其他资源。

作者在文章末尾提供了一个指向他的并行 DNS 解析器的链接:https://github.com/majek/goplayground/blob/master/resolve/resolve.go

他使用可配置数量的 go-routines,所有这些都通过同一个 UDP 端口进行通信。我猜如果你想使用 TCP,你必须为每个 go-routine 使用 1 个 tcp 连接(go-routines 的数量远低于 1000)

关于go - 在 Go 中发送多个请求时出现零星的 EOF 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37727448/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com