2011-10-31 19 views
10

Mam prostą aplikację kliencką serwera. Wszystko działa, ale w pewnym momencie uzyskanie odpowiedzi z serwera wymaga więcej niż 5 minut (co jest normalne i tak musi być). Problem polega na tym, że jeśli zajmie to więcej niż 5 minut, otrzymuję ten wyjątek: java.net.SocketTimeoutException: Read timed out.Java, zwiększenie limitu czasu gniazda

Tak więc zastanawiałem się, czy jest jakiś domyślny limit czasu gniazda w oknach lub na maszynie wirtualnej Java, którą mogę ustawić? Nie mogę zmienić kodu klienta, więc setSoTimeout() nie jest dla mnie opcją.

Korzystanie z systemu Windows XP ..

EDIT: Jak rozumiem teraz jest to, że gra gniazdo nie jest otwarty po stronie klienta. Jest przekazywany z serwera. Tak więc dekompilowałem allso plik jar serwera. Ale wciąż nie mogę znaleźć niczego na temat limitu czasu.

+0

Sprawdź, czy limit czasu został skonfigurowany przy użyciu właściwości systemu. – JimmyB

+0

@HnonoBinder, czy możesz wyjaśnić, co masz na myśli, mówiąc o właściwościach systemu? – hs2d

+0

Mam na myśli coś takiego jak [sun.net.client.defaultReadTimeout] (http://download.oracle.com/javase/1.4.2/docs/guide/net/properties.html) lub cokolwiek może mieć wpływ na sposób twojego klienta łączenia. – JimmyB

Odpowiedz

10

Domyślny limit czasu gniazda wynosi 0, co oznacza, że ​​nigdy nie ma limitu czasu. Jeśli upłynie czas po 5 minutach, oznacza to, że został ustawiony w kodzie. Jeśli źródło nie jest dostępne i nie ma konfiguracji, możesz spróbować dekompilować klasę i wyszukać połączenia setSoTimeout.

Od czasu komentarzy oraz faktu, że wyszukiwania nie znalazły żadnych wywołań setSoTimeout(), można zastosować inne podejście. Po prostu pozwól, aby upłynął czas i napisz mały skrypt, który będzie ponawiał próbę połączenia, na wypadek gdyby tak się stało. Jeśli możesz zadzwonić do klienta z wiersza poleceń, możesz przeanalizować wyjście, jeśli uruchomi się stderr.

+0

Dekompilowałem i szukałem połączeń 'setSoTimeout', ale niczego nie znalazłem. Musi to być gdzieś indziej? – hs2d

8

Utrzymywanie nieużywanego połączenia TCP przez długi czas bez żadnego ruchu nie jest takie proste. Wiele zapór/routerów zamyka nieużywane porty po pewnym czasie oczekiwania.

Jedną z opcji może być zaimplementowanie prostego protokołu keepalive do wysyłania pakietów-dummy co jakiś czas, ale jeśli nie możesz dotknąć kodu klienta, prawdopodobnie nie jest to możliwe.

Edycja: Nie jestem świadomy żadnego sposobu, aby zastąpić setSoTimeout() ustawione w kodzie klienta.

+0

bardzo dobry pomysł z pakietem keep alive! – benez

+0

@benez Nie zgadzam się. Jeśli router uważa połączenie za tak cenny zasób, że go przekracza, nie masz żadnego biznesu, który nakłania go do jego otwarcia. W każdym razie nadal masz do czynienia ze stratami połączeń. Dodanie podtrzymujących pingów to po prostu bezsensowny ból w szyi. – EJP

+0

@EJP Nie widziałem jeszcze odpowiedniej implementacji do obsługi utraty połączenia. zdarzają się przypadki, w których czekasz na aktualizacje w czasie rzeczywistym i potrzebujesz stałej łączności dwóch stron, aby synchronizować dane. straty połączenia nie są po prostu obsługiwane przy prostym ponownym połączeniu. przegapisz ważną wiadomość lub spóźnisz się. na przykład giełdy zawsze wysyłają bicie serca, a protokół IRC wymaga odpowiedzi na ping z pongiem. i tak, masz do czynienia ze stratami połączenia, ale możesz ich uniknąć w niektórych programach. – benez

0

Odpowiedź, że 0 to domyślny limit czasu, nie jest całkiem prawdziwy. Ponieważ na przykład klient Axis2 ma domyślny limit czasu wynoszący 60 sekund, więc będzie zależał od tego, jakiego rodzaju implementacji używasz do wykonania połączenia.

Czy możesz podać więcej szczegółów? Przepraszamy za pisanie w sekcji odpowiedzi, ale nie mam wystarczającej reputacji, aby komentować :)

+0

Patrząc na kod, widzę tylko 'java.io.InputStream'. Więc połączenie musi być wykonane z serwera do klienta? – hs2d

+0

cóż, tak, dla Javy wartość domyślna jest nieskończona, ale biblioteka może to zmienić. Może podpowiedź, hs2d, czy masz jakiś słoik? A może możesz przyjąć inne podejście, po prostu pozwól mu przerwać i spróbuj ponownie, jeśli się nie powiedzie. – stivlo

0

Czy potrzebujesz utrzymywać połączenie przy życiu? Dlaczego nie przemyślisz go ponownie, aby był bardziej asynchroniczny. Ten schemat w ogóle się nie skaluje. W pewnym momencie wszystkie dostępne wątki mogą czekać na długi czas reakcji serwera.

+0

Musi utrzymywać połączenie przy życiu, jeśli chce z niego czytać. Nie można tego zrobić z głową ani ogonem. – EJP

Powiązane problemy