GetHostEntry ist sehr langsam
Ich habe eine WinForms app, und ich bin versucht zu bekommen, reverse DNS-Einträge für eine Liste der IP-Adressen auf dem Formular angezeigt.
Die wichtigste Frage, die ich habe, laufen in System.Net.Dns.GetHostEntry ist lächerlich langsam, besonders, wenn kein reverse-DNS-Eintrag gefunden wird. Mit geraden DNS, dieser sollte schnell sein, da der DNS-server zurück, die NXDOMAIN. Intern ruft ws2_32.dll getnameinfo(), die besagt, "Namensauflösung von Domain-Namen-System (DNS), einer lokalen hosts-Datei, oder durch andere Namensgebung Mechanismen" - also ich nehme an es ist die "andere Namensgebung Mechanismen", die es verursacht zu sein, so langsam, aber wer weiß, was die Mechanismen sind?
Dies ist im Allgemeinen unter 5 Sekunden pro IP, es sei denn, es findet ein reverse-Eintrag, und dann ist es fast sofort. Ich habe teilweise gearbeitet, um dieses mit threads, aber da ich eine große Liste, und ich kann nur laufen so viele Fäden auf einmal, es dauert noch eine Weile, bis durch Sie alle.
Gibt es einen besseren Weg zu finden, reverse DNS-Einträge an, wird schneller sein?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Leider gibt es keine Möglichkeit (die ich kenne) so ändern Sie das Zeitlimit in der Windows-API, auf der client-Seite. Das beste, was Sie tun können, ist, Bearbeiten Sie die Registrierung ändern, um die Länge des timeouts in DNS-Abfragen. Sehen in diesem technet-Artikel für details. Meines Wissens nach, versuche 1, 2, & 3 ausgeführt werden, wenn Sie dies tun, damit die 5-Sekunden-Verzögerung.
Die einzige andere Möglichkeit ist die Verwendung einer form der Hintergrundverarbeitung, wie diese asynchrone version der reverse-DNS-lookups. Dies ist zu verwenden threading, obwohl, so dass Sie schließlich laufen in den Timeout (es werde besser sein, da es in vielen wartenden threads, aber noch nicht perfekt). Persönlich, wenn Sie gehen, um Prozess-eine riesige Zahl, ich würde eine Kombination beider Ansätze - führen Sie einen reverse-lookup-ansyncrhonously UND ändern Sie die Registrierung, um die timeout-kürzer.
Bearbeiten nach Kommentare:
Wenn Sie einen Blick auf die Fahnen auf getnameinfo, es ist ein flags-parameter. Ich glaube, man kann P/Invoke in diese und setzen Sie das Kennzeichen
NI_NAMEREQD | NI_NUMERICHOST
um das Verhalten, das Sie nach sind. (Der erste, der sagt, dass Fehler sofort aus, wenn es keinen DNS-Eintrag, die hilft, den timeout - das zweite zu tun, sagt der reverse-lookup.)Vielleicht kann das helfen? Die WayBack Machine version der Toter link.
(Dead link: http://www.chapleau.info/blog/2008/09/09/reverse-dns-lookup-with-timeout-in-c.html)
Den code für die Nachwelt:
Können Sie verbessern die Geschwindigkeit eines gescheiterten lookup wesentlich durch die Abfrage der in-addr.arpa domain. E. g führen Sie einen reverse-IP-lookup für die IP-Adresse A. B. C. D sollten Sie eine DNS-Abfrage für die domain D. C. B. A. in-addr.arpa. Wenn reverse-lookup möglich ist, einen PTR-Datensatz mit dem host name zurückgegeben wird.
Leider .NET nicht über eine Allgemeine API für die Abfrage von DNS. Aber mithilfe von P/Invoke aufrufen können Sie die DNS-API, um das gewünschte Ergebnis zu erhalten (die Funktion zurück
null
wenn der reverse-lookup).Falls jemand trifft dies...
Wechselte ich von der Verwendung der TcpClient Konstruktor zum Aufruf der veralteten Dns.GetHostByName statt.
Aus welchem Grund auch immer es führt viel besser.
Hauptsächlich einen Kommentar hinzuzufügen, im Falle, jemand findet diese über google, wie ich es Tat...
Kann das Verhalten sein, die OS-version konkret; diese Hinweise gelten für Server 2008 R2.
Den NI_NUMERICHOST flag nicht tun, was Sie wollen; in diesem Fällen die API-Rückgabe der numerische version der host-id (z.B. IP-Adresse), statt dem host Namen.
Sogar mit NI_NAMEREQD, es ist immer noch ein timeout, wenn die Informationen nicht gefunden (5 Sekunden, Standard). Ich bin mir nicht sicher, ob dies aufgrund einer kaskadierenden lookup timeout, oder etwas anderes, aber dieses flag verhindert nicht, dass das timeout (oder jede andere Flagge, soweit ich das sagen kann).
Es scheint, dass diese Anrufe die WSALookupService API-intern, obwohl es ist unklar, welche flags übergeben werden. Beachten Sie auch, dass die zurückgegebenen Informationen können falsch sein; in einem meiner test-Fällen, nslookup zurückgegeben wird kein Ergebnis, sondern getnameinfo zurück, wie ungenau und unqualifizierte Namen. So... ja, keine gute Antwort, aber ich hoffe diese Informationen sind hilfreich.