2013-07-03 10 views
9

Recentemente ho notato un problema con la mia applicazione e penso che sia dovuto al fatto che non uso correttamente boost::asio e don ' t capire cosa fa un resolver tcp.Differenza tra la risoluzione di una query e la creazione di un endpoint con IP e porta (in boost asio)

Fondamentalmente, utilizzo uno boost::asio::ip::tcp::resolver per ottenere gli endpoint a cui connettersi.

Quello che ho scoperto di recente è che può venire con più di un endpoint (in particolare quando mi collego all'host locale).

Al momento richiedo uno async_connect su tutto il punto finale. Non sono sicuro al 100%, ma penso che sia male. Dovrei andare da loro una a una richiesta async_connect, attendere la risposta e provare su quella successiva se e solo se fallisce.

Quindi, in pratica, sapendo che ho due scelte, se voglio usare async_connect su quei punti finali:

  1. rifattorizziamo il mio codice in modo che il mio async_connect fallimento di gestire correttamente e in caso di errore tenta di collegarsi all'altro disponibili endpoint. Dovrei passare quindi l'iteratore dell'endpoint.

  2. cadere il resolver e utilizzare un endpoint costruisco me stesso in questo modo: boost::asio::ip::tcp::endpoint("localhost", 20015)

I tipi di avere la sensazione che dovrei usare la prima soluzione e che il risolutore sta portando qualcosa di più che l'auto endpoint costruito.

Ma cosa porta il risolutore e in che modo l'auto-costruito si risolve da solo?

risposta

11

Mentre Sam ha risposto sinteticamente come la maggior parte delle applicazioni gestiscono la creazione di endpoint, ho voluto espandere il numero resolver.

Il resolver viene utilizzato per convertire rappresentazioni testo leggibile di un indirizzo nella endpoint (s) che contiene il formato binario strutturato per un indirizzo tramite hostname resolution o conversioni tra rappresentazioni definite. Ad esempio, lo resolver può risolvere il leggibile da "localhost" a 0x7F000001 o convertire in 0x7F000001. Boost.Asio utilizza o emula getaddrinfo() per eseguire questa risoluzione. Per la risoluzione asincrona, verrà creato un thread interno per eseguire l'operazione.

D'altra parte, un basic_endpoint non si risolve da solo. Anche se non può essere costruito con una stringa e una porta, può essere costruito con un ip::address e una porta.Il ip::address può essere costruito da una stringa in forma decimale puntata (IPv4) o notazione esadecimale (IPv6):

namespace ip = boost::asio::ip; 
ip::tcp::endpoint(ip::address::from_string("127.0.0.1"), 20015); 

Fornire un nome host a ip::address::from_string() genererà un'eccezione:

namespace ip = boost::asio::ip; 
ip::address::from_string("localhost"); // throws boost::system::system_error 

Alla fine, utilizzare:

  • resolver quando si desidera supportare la risoluzione nome host o conversioni IP. Ciò è particolarmente utile quando gli IP possono cambiare, ma i nomi degli host rimangono gli stessi, o quando un singolo host può decidere di IP multipli.
  • ip::address::from_string() per creare un indirizzo da una IP.
4

È corretto che la connessione a tutti gli endpoint restituiti dall'operazione di risoluzione non è probabile quale si aspetta l'applicazione. La scelta n. 2 non funzionerà poiché non esiste un costruttore per un basic_endpoint(const char*, int). La scelta n. 1 è il modo in cui sono strutturati diversi esempi di asio, in particolare lo async tcp client demonstrating timeouts.

Il refactoring del codice per includere lo endpoint_iterator restituito dal resolver non dovrebbe essere troppo difficile, seguire l'esempio precedente se si hanno problemi. Si noti che utilizza un blocco resolve() e non async_resolve(), il concetto è lo stesso comunque.

+1

Grazie per la risposta, è molto utile. Ho scoperto, tuttavia, che l'uso asincrone risoluzione era irregolare (la mia piattaforma è la finestra e ho spesso ottenere '' 995' errore WSA_OPERATION_ABORTED'). Così ho optato per una soluzione intermedia con determinazione sincrono e asincrono iterativo collegare su ogni punto finale, e sì refactoring il mio codice è stato facile. – Arthur

Problemi correlati