ConnectionTimeout a SocketTimeout

139

Mam problem z biblioteką, której używam. Może to być biblioteka albo ja źle ją wykorzystuję!

Zasadniczo, kiedy to robię (limit czasu w milisekundach)

_ignitedHttp.setConnectionTimeout(1);  // v short
_ignitedHttp.setSocketTimeout(60000);  // 60 seconds

Nie jest generowany żaden wyjątek limitu czasu i działa poprawnie, jednak gdy wykonuję następujące czynności,

_ignitedHttp.setConnectionTimeout(60000);  // 60 seconds
_ignitedHttp.setSocketTimeout(1);          // v short

Otrzymuję wyjątek dotyczący gniazda.

Więc moje pytanie brzmi: dlaczego nie mogę zasymulować wyjątku połączenia? Czy nie rozumiem różnicy między gniazdem a przekroczeniem limitu czasu połączenia? Biblioteka jest tutaj (jeszcze nie została oficjalnie wydana).

Robert
źródło

Odpowiedzi:

235

Limit czasu połączenia pojawia się dopiero po uruchomieniu połączenia TCP. Dzieje się tak zwykle, gdy urządzenie zdalne nie odpowiada. Oznacza to, że serwer został zamknięty, użyto złej nazwy IP / DNS, złego portu lub przerwano połączenie sieciowe z serwerem.

Limitu czasu gniazdo jest przeznaczony do ciągłego monitorowania przychodzącego strumienia danych. Jeśli przepływ danych zostanie przerwany na określony czas, połączenie jest traktowane jako wstrzymane / zerwane. Oczywiście działa to tylko w przypadku połączeń, w których dane są odbierane przez cały czas.

Ustawienie limitu czasu gniazda na 1 wymagałoby, aby co milisekundę otrzymywano nowe dane (zakładając, że dobrze czytasz blok danych, a blok jest wystarczająco duży)!

Jeśli tylko strumień przychodzący zatrzymuje się na dłużej niż milisekundę, dochodzi do przekroczenia limitu czasu.

Robert
źródło
1
Czy możesz kiedykolwiek uzyskać limit czasu połączenia, jeśli serwer nie jest wyłączony, ale jest zajęty? A może byłby to limit czasu gniazda?
Robert,
9
To zależy - jeśli połączenie TCP zostało nawiązane przed przeciążeniem serwera, otrzymasz wyjątek gniazda - w przeciwnym razie otrzymasz wyjątek połączenia, wskazujący, że nie można nawiązać połączenia TCP.
Robert,
2
Biorąc pod uwagę duże opóźnienia szczególnie starszych sieci komórkowych, limit czasu połączenia musi być ustawiony na kilka sekund (np. 10s lub lepiej 10000 msec). Limit czasu gniazda ustawiłbym tylko wtedy, gdy nie używasz kilku połączeń, ponieważ HTTP może ponownie użyć połączenia po żądaniu.
Robert,
1
Czy to oznacza, że ​​jeśli ustawisz limit czasu gniazda (np. 1 min), połączenie zostanie przerwane po 1 minucie bezczynności, gdzie normalnie zostanie ponownie użyte, jeśli nie ustawiono limitu czasu?
Robert,
2
@Robert Niekoniecznie otrzymasz wyjątek połączenia, jeśli serwer jest zbyt zajęty. Jest zależny od platformy, na platformie serwera. Limit czasu odczytu gniazda nie przerywa połączenia. Po prostu powoduje SocketTimeoutException. Decyzja, czy połączenie jest nadal możliwe do wykorzystania, jest decyzją, którą musi podjąć aplikacja. Z pewnością w API nie ma nic, co mówi, że nie można próbować więcej wejść / wyjść w gnieździe. Twoje stwierdzenie o nie używaniu limitów czasu, jeśli korzystasz z wielu połączeń, nie zaczyna mieć sensu. Za dużo dezinformacji.
Markiz Lorne,
91

Limit czasu połączenia to maksymalny czas, przez jaki program jest gotów czekać, aby skonfigurować połączenie do innego procesu. W tym momencie nie otrzymujesz ani nie publikujesz żadnych danych aplikacji, po prostu ustanawiasz połączenie.

Timeout gniazdo jest limit czasu podczas oczekiwania na poszczególne pakiety. Powszechnym błędem jest przekonanie, że przekroczenie limitu czasu gniazda to limit czasu na otrzymanie pełnej odpowiedzi. Więc jeśli masz limit czasu gniazda wynoszący 1 sekundę i odpowiedź złożoną z 3 pakietów IP, gdzie każdy pakiet odpowiedzi dociera do 0,9 sekundy, co daje całkowity czas odpowiedzi 2,7 sekundy, nie będzie limitu czasu.

entpnerd
źródło
4
W porządku. 1. Czy możemy więc powiedzieć, że SocketTimeout pojawia się tylko wtedy, gdy połączenie jest już ustanowione? 2. Co się stanie, jeśli nie ma przepływu danych przez powiedzmy 5 minut po odebraniu 3 pakietów? Czy po odebraniu trzeciego pakietu wystąpi wyjątek SocketTimeout?
Saurabh Patil
4
@SaurabhPatil 1. Tak. Potwierdzenie można znaleźć w technicznym omówieniu protokołu HTTP w serwisie Wikipedia . 2. Po wysłaniu końca wiadomości dalsze dane nie są potrzebne, więc nie nastąpi przekroczenie limitu czasu gniazda. Zobacz tę odpowiedź na ten temat.
entpnerd
9
Żałuję, że nie nazwali „limitu czasu gniazda” jako „limitu czasu bezczynności”.
Manish Maheshwari
Jeśli limit czasu gniazda wynosi 1 sekundę, a odpowiedź składa się z 3 pakietów IP, przy czym każdy pakiet odpowiedzi dociera w 0,8 sekundy, a między pierwszym a drugim pakietem jest przerwa 0,3 sekundy. Wtedy całkowity czas odpowiedzi nadal wynosi 2,7 sekundy, ale nastąpi przekroczenie limitu czasu gniazda.
Anderson