Piszę aplikację w języku C, która jest uruchamiana jako systemd service przy starcie (dystrybucja: Arch Linux) i która ma połączyć się z serwerem. Ponieważ aplikacja jest uruchamiana podczas rozruchu, w końcu zdarza się, że połączenie sieciowe nie zostało jeszcze ustanowione. To naturalnie prowadzi do niepowodzenia pierwszej funkcji, która wymaga jednej, która w moim przypadku to getaddrinfo
.Jeśli polecenie getaddrinfo zakończy się niepowodzeniem, gdy zakończy się niepowodzeniem na zawsze (nawet po uruchomieniu sieci)
Tak więc pomyślałem, że po prostu napiszę pętlę, która wielokrotnie wywołuje getaddrinfo
, aż do momentu, gdy sieć będzie gotowa. Niestety, stwierdziłem, że getaddrinfo
nadal nie działa z name or service not known
nawet po nawiązaniu połączenia.
Mogę wysłać polecenie ping do serwera za pomocą jego nazwy hosta, ale nadal nie będzie można tego zrobić za pomocą usługi getaddrinfo
. Jeśli zatrzymam aplikację i uruchomię ją ponownie, wszystko będzie działać poprawnie. Jeśli połączenie sieciowe jest już ustanowione przed pierwszym połączeniem, działa również dobrze.
Wygląda na to, że jeśli getaddrinfo
raz się nie powiodło, ponieważ sieć nie była gotowa, zakończy się niepowodzeniem na zawsze. Wydaje się, że nie zdajemy sobie sprawy z istniejącego połączenia. Podczas korzystania z wycofanego gethostbyname
zachowanie jest takie samo.
Jaki jest powód takiego zachowania? Czy istnieje sposób na wymuszenie odświeżenia zmiennych wewnętrznych (jeśli takie istnieją) lub podobnych, które mogłyby wyjaśnić, dlaczego funkcja nadal uważa, że nie ma połączenia? Czy istnieje inna funkcja, którą powinienem wcześniej wywołać, aby sprawdzić, czy sieć jest gotowa?
Chciałbym uniknąć opóźnienia, które czeka przez pewien czas, oczekując, że sieć zostanie później podłączona. Wolałbym też sprawdzić połączenie z poziomu mojej aplikacji i nie mieć najpierw skryptu bash, a następnie uruchomić aplikację.
Przez to miałem na myśli res_init() w pętli. –
To faktycznie działa czasami (ale raczej rzadko). Zakładam, że działa, jeśli połączenie sieciowe jest już ustanowione, ale 'resolv.conf' nie został jeszcze zaktualizowany podczas uruchamiania aplikacji. Po aktualizacji 'resolv.conf', wywołanie' res_init' w pętli ładuje nową konfigurację, a następnie 'getaddrinfo'. Ale jeśli połączenie sieciowe nie jest gotowe do uruchomienia aplikacji, nadal nie działa, – kassiopeia
Moje demo krok po kroku polega na uruchomieniu aplikacji, gdy w ogóle nie skonfigurowano rozdzielczości DNS, co miałoby miejsce, gdyby nie istniały połączenia sieciowe. Czy próbowałeś uruchomić kod demo za pomocą wywołania rs_init() bez połączenia sieciowego, a następnie łączenia się z siecią? Ten krótki mały kod demonstracyjny jest dość łatwy do przetestowania. Nie musisz niczego zakładać. –