Więc zrobiłem kilka testów. Na podstawie moich wyników jest jasne, że zależą one od implementacji systemu operacyjnego. Dla porównania przetestowałem to z jądrowym kernelem Fedory: 2.6.35.10-74.fc14.x86_64
.
Najważniejsze jest to, że async_resolve()
wygląda na to jedyny przypadek, w którym może móc uciec bez ustawiania deadline_timer
. Jest to praktycznie wymagane w każdym innym przypadku dla rozsądnego zachowania.
async_resolve()
Wywołanie async_resolve()
skutkowało 4 zapytań 5 sekund od siebie. Handler został wywołany 20 sekund po żądaniu z błędem boost::asio::error::host_not_found
.
Mój resolver domyślnie przyjmuje 5-sekundowy limit czasu z 2 próbami (resolv.h
), więc wydaje się, że wysyła dwa razy więcej skonfigurowanych zapytań. Zachowanie można modyfikować, ustawiając options timeout
i options attempts
w /etc/resolv.conf
. W każdym przypadku liczba wysłanych zapytań była dwukrotnie większa, niż ustawiono attempts
, a handler został wywołany z błędem host_not_found
.
Dla testu pojedynczy skonfigurowany serwer nazw był routowany w czarnej dziurze.
async_connect()
Wywołanie async_connect()
z black-hole-kierowane okolicy spowodowało handler miano z błędem boost::asio::error::timed_out
po ~ 189 sekund.
Stos wysłał początkowy SYN i 5 ponownych prób. Pierwsza próba została wysłana po 3 sekundach, a czas oczekiwania na powtórzenie podwaja się za każdym razem (3 + 6 + 12 + 24 + 48 + 96 = 189). Liczba powtórzeń mogą być zmieniane:
% sysctl net.ipv4.tcp_syn_retries
net.ipv4.tcp_syn_retries = 5
Domyślnym 5 wybrany jest zgodne z RFC 1122 (4.2.3.5):
[programatorów retransmisji] dla segmentu SYN musi być ustawić wystarczająco duży, aby zapewnić retransmisję segmentu przez co najmniej 3 minuty. Aplikacja może zamknąć połączenie (tj. Zrezygnować z próby otwarcia) wcześniej, oczywiście.
3 minuty = 180 sekund, chociaż w RFC nie określono górnej granicy. Nic nie powstrzyma implementacji przed ponowną próbą na zawsze.
async_write()
Dopóki bufor wyślij gniazda nie była pełna, uchwyt ten nazywany był zawsze od razu.
Mój test ustanowił połączenie TCP i minutę później ustaw czasomierz, aby zadzwonić pod numer async_write()
. Podczas minutę którym połączenie zostało nawiązane, ale przed wywołaniem async_write()
, próbowałem wszelkiego rodzaju chaos:
- Ustawienie routera do dalszego czarno-dołkowego późniejszego ruchu do miejsca przeznaczenia.
- Wyczyszczenie sesji w zaporze sieciowej, aby odpowiadała fałszywymi sygnałami RST od miejsca docelowego.
- Odłączenie mojego Ethernet
- Running
/etc/init.d/network stop
Bez względu na to, co zrobiłem, następny async_write()
natychmiast zadzwonić do jego obsługi zgłosić sukces.
W przypadku, gdy zapora fałszywej RST, połączenie zostało natychmiast zamknięte, ale nie miał możliwości dowiedzenia się, że dopóki nie próbował następny operację (co natychmiast zgłosić boost::asio::error::connection_reset
). W innych przypadkach połączenie pozostanie otwarte i nie będzie zgłaszało mi błędów, aż w końcu upłynie 17-18 minut później.
Najgorszy przypadek dla async_write()
dotyczy tego, czy host wysyła retransmisje, a bufor wysyłania jest pełny.Jeśli bufor jest pełny, async_write()
nie wywoła jego obsługi do czasu upłynięcia czasu retransmisji. domyślne Linux do 15 retransmisji:
% sysctl net.ipv4.tcp_retries2
net.ipv4.tcp_retries2 = 15
Czas pomiędzy retransmisji większą od siebie (i zależy od wielu czynników, takich jak w przewidywanym czasie obie specyficznego połączenia), lecz jest zaciśnięta na 2 minuty. Tak więc przy domyślnych 15 retransmisjach i najgorszym 2-minutowym limicie czasu górna granica wynosi 30 minut, aby wywołać procedurę obsługi async_write()
. Po wywołaniu błąd jest ustawiony na boost::asio::error::timed_out
.
async_read()
To nigdy nie powinno się nazywać jego obsługi o ile połączenie zostanie ustanowione i nie jest odbierany danych. Nie miałem czasu go przetestować.
Musiałem również trzymać się własnego "deadline_timer", więc byłbym bardzo zainteresowany, aby zobaczyć, czy to nie jest konieczne. – chrisaycock
+1 interesujące pytanie. Myślę, że odpowiedź byłaby w dużej mierze zależna od platformy. Zakładam, że zależy ci na Linuksie? –