Jak naprawić java.net.SocketException: uszkodzony potok?
Używam klienta http apache commons do wywoływania adresu URL z metodą post do wysyłania parametrów i rzadko daje to poniższy błąd.
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at org.apache.commons.httpclient.methods.ByteArrayRequestEntity.writeRequest(ByteArrayRequestEntity.java:90)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
Czy ktoś może zasugerować, co powoduje ten wyjątek i jak go debugować?
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
10 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Tak więc w obu przypadkach masz źle zdefiniowany lub zaimplementowany protokół aplikacji.
Jest trzeci powód, którego tutaj nie będę dokumentować, ale który polega na tym, że peer podejmuje celowe działania w celu ponownego uruchomienia, zamiast prawidłowego zamykania połączenia.
Anonimowy użytkownik
Potwierdzenie od:
Spróbuj zwiększyć ilość pamięci dostępnej dla maszyny JVM i/lub monitoruj użycie pamięci, gdy wystąpią te błędy.
Anonimowy użytkownik
Potwierdzenie od:
Jest to bardzo częsty wyjątek w aplikacjach typu klient/serwer, które odbierają ruch od klientów lub serwerów poza kontrolą aplikacji. Na przykład klient jest przeglądarką. Jeśli przeglądarka wykona połączenie Ajax i/lub użytkownik po prostu zamknie stronę lub przeglądarkę, może skutecznie nieoczekiwanie przerwać całą komunikację. Zasadniczo zobaczysz ten błąd za każdym razem, gdy drugi koniec wyjdzie ze swojej aplikacji, a tego się nie spodziewałeś.
Jeśli napotkasz ten wyjątek w swojej aplikacji, oznacza to, że powinieneś sprawdzić kod, w którym dzieje się IO (wejście/wyjście) i zawinąć go blokiem try/catch, aby złapać ten IOException. To wtedy decydujesz, jak chcesz sobie poradzić z tą na wpół wyimaginowaną sytuacją.
W twoim przypadku najwcześniejszym miejscem, nad którym nadal masz kontrolę, jest wywołanie - więc upewnij się, że zawinąłeś wywołanie w bloku try/catch i obsłużono je w dowolny sposób.
Zdecydowanie odradzam rejestrowanie błędów specyficznych dla SocketException-Broken Pipe na jakimkolwiek poziomie innym niż debug/trace. Może również służyć jako forma ataku DOS (Denial of Service) poprzez wypełnianie dzienników. Spróbuj wzmocnić i negatywnie przetestować aplikację pod kątem tego typowego scenariusza.
Anonimowy użytkownik
Potwierdzenie od:
Przed:
Po:
Anonimowy użytkownik
Potwierdzenie od:
Aby rozwiązać ten wyjątek, zawsze musisz rozłączyć się z poprzednią sesją i utworzyć nową instancję klienta oraz nowe połączenie z serwerem. To samo podejście może być również przydatne w przypadku klienta HTTPClient.
Anonimowy użytkownik
Potwierdzenie od:
Po zbadaniu sprawy znalazłem rozwiązanie, które rozwiązuje mój problem. Wiem, że to pytanie jest dość stare, ale wolę podzielić się moim rozwiązaniem, ktoś może uznać je za przydatne.
Problem polegał na utworzeniu ServerSocket. Czytałem z dokumentacji, że jest limit 50 gniazd. Jeśli spróbujesz otworzyć inne połączenie, zostaną one odrzucone. Rozwiązaniem jest po prostu zmiana tej domyślnej konfiguracji po stronie serwera. W poniższym przypadku tworzę serwer gniazd, który nasłuchuje na porcie TCP i akceptuje maksymalnie oczekujących gniazd.
<pre class="lang-java prettyprint-override">
Z Javadoc z
ServerSocket
https://docs.oracle.com/javase ... .html
:
Maksymalna długość kolejki do wskazywania połączenia przychodzącego (żądania połączenia) jest ustawiana w parametrze backlog. Jeśli wskazanie połączenia pojawia się, gdy kolejka jest pełna, połączenie jest odrzucane.
Anonimowy użytkownik
Potwierdzenie od:
To tylko zgadywanie. Po ponownym wdrożeniu plików klas aplikacji serwera i ponownym przetestowaniu problem „Uszkodzony potok” zniknął.
Anonimowy użytkownik
Potwierdzenie od:
Czasami tomcat nie zgłasza zepsutego wyjątku pip, ponieważ wyjątek timeout zamyka połączenie, dlaczego taka różnica też mnie dezorientuje.
Anonimowy użytkownik
Potwierdzenie od:
Maksymalna długość kolejki do wskazania połączenia przychodzącego (a
żądanie połączenia) jest ustawiona na 50. Jeśli pojawi się wskazanie połączenia
gdy kolejka jest pełna, połączenie jest odrzucane.
Na przykład należy zwiększyć parametr „backlog” swojego ServerSocket
Anonimowy użytkownik
Potwierdzenie od: