Sto scrivendo un'applicazione C che viene eseguita come systemd service all'avvio (distro: Arch Linux) e che deve connettersi a un server. Poiché l'applicazione viene eseguita all'avvio, alla fine capita che la connessione di rete non sia ancora stata stabilita. Ciò porta naturalmente a un fallimento della prima funzione che ne richiede uno, che nel mio caso è getaddrinfo
.Se getaddrinfo fallisce una volta fallisce per sempre (anche dopo che la rete è pronta)
Quindi ho pensato di scrivere un ciclo che chiama ripetutamente lo getaddrinfo
finché non supera una volta che la rete è pronta. Purtroppo ho trovato che getaddrinfo
continua a non riuscire con name or service not known
anche dopo che la connessione è stata stabilita.
Sono in grado di eseguire il ping del server tramite il relativo nome host ma non lo eseguirà ancora getaddrinfo
. Se interrompo l'applicazione ed eseguo di nuovo, tutto funziona correttamente. Se la connessione di rete è già stabilita prima della prima chiamata, getaddrinfo
funziona correttamente.
Apparentemente, se getaddrinfo
non è riuscito una volta perché la rete non era pronta, fallirà per sempre. Sembra non essere a conoscenza della connessione ora esistente. Quando si utilizza il deprecato gethostbyname
, il comportamento è lo stesso.
Qual è il motivo di questo comportamento? C'è un modo per forzare getaddrinfo
per aggiornare le variabili interne (se esistono) o simili che potrebbero spiegare perché la funzione crede ancora che non vi sia alcuna connessione? Esiste un'altra funzione che dovrei chiamare in precedenza per verificare se la rete è pronta?
Vorrei evitare un ritardo che attende un po 'di tempo, aspettando che la rete sia collegata in seguito. Preferirei anche controllare una connessione dalla mia applicazione e non avere uno script bash prima di controllarlo e quindi avviare l'applicazione.
Con ciò intendevo res_init() all'interno del ciclo. –
A volte funziona (ma piuttosto di rado). Suppongo che funzioni se la connessione di rete è già stata stabilita, ma 'resolv.conf' non è stato ancora aggiornato quando l'applicazione viene avviata. Una volta che 'resolv.conf' viene aggiornato, la chiamata a' res_init' nel loop carica la nuova configurazione e quindi 'getaddrinfo' supera. Ma se la connessione di rete non è pronta all'avvio dell'applicazione, continua a non riuscire, – kassiopeia
La mia demo dettagliata prevede l'avvio dell'applicazione quando non è configurata alcuna risoluzione DNS, il che sarebbe il caso quando non esistono connessioni di rete. Hai provato ad avviare il codice demo con la chiamata a rs_init() senza una connessione di rete e quindi a collegarti a una rete? Questo breve codice demo è abbastanza semplice da testare. Non c'è bisogno di assumere nulla. –