2016-11-22 3 views
2

Ich bin ein wenig verwirrt darüber, welche Art von Resolver ich für ein Nebenprojekt verwenden soll, an dem ich arbeite. Ich finde die Antwort nicht in der Asio-Dokumentation.Welche Art von Asio Resolver-Objekt sollte ich verwenden?

Ich weiß, dass DNS mit UDP oder TCP arbeiten kann und dass größere Antworten in der Regel über TCP gesendet werden.

asio bietet sowohl ip :: tcp :: resolver als auch ip :: udp :: resolver an.

  • Kann ich sie austauschbar verwenden?
  • Nachdem ich den Namen zu einem Endpunkt aufgelöst habe, plane ich, mit einen TCP-Socket zu verbinden. Bedeutet das, dass ich einen ip :: tcp :: resolver verwenden muss?

Wenn es in der Tat sind austauschbar:

  • Gibt es einen Performance-Vorteil des UDP-Resolver zu verwenden?
  • Gibt es einen weiteren Vorteil für die Verwendung des TCP-Resolvers?
  • Wenn ich UDP-Resolver verwende, muss ich mich damit befassen, dass die Antwort zu groß für die UDP-Suche ist und es mit TCP versucht? (Ich erwarte eine Verbindung zu einem CDN, der zu mehreren IP-Adressen pro Host auflöst.)

Antwort

3

Verwenden Sie den Resolver, der das gleiche Protokoll wie der Socket hat. Zum Beispiel erwartet tcp::socket::connect() eine tcp::endpoint, und der über udp::resolver::iterator bereitgestellte Endpunkttyp ist udp::endpoint. Der Versuch, direkt das Ergebnis der Abfrage von einem anderen Protokoll in einem Übersetzungsfehler führt zu verwenden:

boost::asio::io_service io_service; 
boost::asio::ip::tcp::socket socket(io_service); 
boost::asio::ip::udp::resolver::iterator iterator = ...; 
socket.connect(iterator->endpoint()); 
// ~~~^~~~~~~ no matching function call to `tcp::socket::connect(udp::endpoint)` 
//   no known conversion from `udp::endpoint` to `tcp::endpoint` 

Weder tcp::resolver noch udp::resolver diktieren das Transportschichtprotokoll der Namensauflösung verwenden. Der DNS-Client verwendet TCP, wenn dies erforderlich ist oder explizit für die Verwendung von TCP konfiguriert wurde.

Auf Systemen, auf denen die Auflösung von Servicenamen unterstützt wird, kann der Resolvertyp bei der Service-Namensauflösung mit einem beschreibenden Servicenamen Auswirkungen auf die Ergebnisse haben. Zum Beispiel in der IANA Service Name and Transport Protocol Port Number Registry:

  • der daytime Dienst verwendet Port 13 auf UDP und TCP
  • der shell Dienst verwendet Port 514 nur auf TCP
  • der syslog Dienst verwendet Port 514 nur auf UDP

Daher kann man tcp::resolver verwenden, um die daytime und shell Service zu lösen, aber nicht syslog. Auf der anderen Seite kann udp::resolverdaytime und syslog auflösen, aber nicht shell. Das folgende Beispiel demonstriert diese Unterscheidung:

#include <boost/asio.hpp> 

int main() 
{ 
    boost::asio::io_service io_service; 

    using tcp = boost::asio::ip::tcp; 
    using udp = boost::asio::ip::udp; 

    boost::system::error_code error; 
    tcp::resolver tcp_resolver(io_service); 
    udp::resolver udp_resolver(io_service); 

    // daytime is 13/tcp and 13/udp 
    tcp_resolver.resolve(tcp::resolver::query("daytime"), error); 
    assert(!error); 
    udp_resolver.resolve(udp::resolver::query("daytime"), error); 
    assert(!error); 

    // shell is 514/tcp 
    tcp_resolver.resolve(tcp::resolver::query("shell"), error); 
    assert(!error); 
    udp_resolver.resolve(udp::resolver::query("shell"), error); 
    assert(error); 

    // syslog is 514/udp 
    tcp_resolver.resolve(tcp::resolver::query("syslog"), error); 
    assert(error); 
    udp_resolver.resolve(udp::resolver::query("syslog"), error); 
    assert(!error); 

    tcp_resolver.resolve(tcp::resolver::query("514"), error); 
    assert(!error); 
    udp_resolver.resolve(udp::resolver::query("514"), error); 
    assert(!error); 
} 
Verwandte Themen