Lassen Sie mich damit beginnen, zu sagen, dass ich neu bin und alle Hinweise/Korrekturen begrüße.Sporadischer EOF-Fehler beim Senden mehrerer Anfragen in Go
Ich versuche, eine kleine Go-Anwendung zu schreiben, die eine Reihe von DNS-Abfragen erstellen und sie in jeweiligen Go-Routinen senden wird. Ich erhalte die URLs aus einer Datei mit 1000 URLs und erstelle ein Slice, für jede URL im Slice mache ich eine Abfrage für den A-Record und schiebe die URL und die verstrichene Zeit an einen Ergebniskanal, falls erfolgreich und wenn ein Fehler bei a auftritt jeweiliger Fehlerkanal. Ich höre dann auf eine Auswahl.
Womit ich kämpfen bin, werde ich (anscheinend nach dem Zufallsprinzip) einen EOF-Fehler für einige meiner Abfragen erhalten, wenn ich TCP benutze und einen I/O Timeout-Fehler empfangen werde, wenn ich UDP benutze. Ich möchte TCP verwenden und eine Antwort sicherstellen, ich bin verloren, warum ich einen EOF-Fehler bekommen würde. Dies geschieht auch, wenn ich 1000 Zugriffen auf den gleichen URL machen vs 1000 verschiedene URLs
Arbeiten auf OSX und Go Version 1.6
Dies ist, was ich bisher:
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)
}
Ausgang:
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
Gedanken, Vorschläge und helfen alle geschätzt. Vielen Dank!
mein erster Gedanke ist, dass Sie etwas überladen, vielleicht die Begrenzung auf X begrenzen gleichzeitige Anfragen würden helfen? – Plato
Ich dachte die gleiche Sache und es scheint wie ~ 200 Abfragen wird kein Fehler ergeben, jedoch bin ich immer noch unsicher, warum EOF und wie man es umgehen kann. Ich möchte in der Lage sein, die Anfragen zu generieren, sie rauszuschieben und auf Antworten zu warten. –