/ / Oficjalne powody „Oprogramowanie spowodowało przerwanie połączenia: błąd zapisu gniazda” - java, wyjątek, gniazda, tomcat, śledzenie stosu

Oficjalne powody "Oprogramowanie spowodowało przerwanie połączenia: błąd zapisu gniazda" - java, wyjątek, gniazda, tomcat, śledzenie stosu

Biorąc pod uwagę ten fragment śledzenia stosu

Przyczyna: java.net.SocketException: Oprogramowanie spowodowało przerwanie połączenia: błąd zapisu gniazda
w java.net.SocketOutputStream.socketWrite0 (natywny Metoda)

Próbowałem odpowiedzieć na następujące pytania:

  1. Jaki kod zgłasza ten wyjątek? (JVM? / Tomcat? / My code?)
  2. Co powoduje zgłoszenie tego wyjątku?

Odnośnie # 1:

Źródło JVM firmy Sun nie zawiera dokładnie tej wiadomości, ale myślę, że tekst Oprogramowanie spowodowało przerwanie połączenia: błąd zapisu gniazda pochodzi z natywnej implementacji SocketOutputStream:

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
int len) throws IOException;

Odnośnie # 2

Domyślam się, że jest to spowodowane, gdy klient mazakończył połączenie przed otrzymaniem pełnej odpowiedzi (np. wysłał zapytanie, ale przed otrzymaniem pełnej odpowiedzi zostało zamknięte / zakończone / offline)

Pytania:

  1. Czy powyższe założenia są prawidłowe (nr 1 i nr 2)?
  2. Czy można to odróżnić od sytuacji: „nie można napisać do klienta z powodu błędu sieci w sieci serwer side ”? czy może to wyświetlać ten sam komunikat o błędzie?
  3. I najważniejsze: Czy istnieje oficjalny dokument (np. Z firmy Sun) zawierający powyższe informacje?

Potrzebuję dowodu, że jest to ślad stosu„błąd” klienta gniazda, a serwer nie mógł nic zrobić, aby go uniknąć. (z wyjątkiem przechwycenia wyjątku lub użycia SocketOutputStream innej firmy niż Sun JVM, chociaż oba tak naprawdę nie unikają faktu, że klient zakończył działanie )

Odpowiedzi:

47 dla odpowiedzi № 1

„Ten błąd może wystąpić, gdy sieć lokalnasystem przerywa połączenie, na przykład gdy WinSock zamyka ustanowione połączenie po niepowodzeniu retransmisji danych (odbiornik nigdy nie potwierdza danych wysyłanych do gniazda strumienia danych). ” ten artykuł MSDN. Zobacz też Niektóre informacje na temat „Oprogramowanie spowodowało przerwanie połączenia”.


9 dla odpowiedzi nr 2

Widziałem to najczęściej, gdy przeszkoda korporacyjnej zapory na stacji roboczej / laptopie, przerywa połączenie.

na przykład. Mam proces serwera i proces klienta na tym samym komputerze. Serwer nasłuchuje na wszystkich interfejsach (0.0.0.0), a klient próbuje połączyć się z interfejsem publicznym / domowym (nie zauważając interfejsu sprzężenia zwrotnego 127.0.0.1).

Jeśli urządzenie ma odłączoną sieć (np. Wi-Fi jest wyłączone), połączenie zostaje nawiązane. Jeśli urządzenie jest podłączone do sieci korporacyjnej (bezpośrednio lub VPN), połączenie zostanie utworzone.

Jednak jeśli urządzenie jest podłączone do publicznegoWi-Fi (lub sieć domowa), a następnie zapora sieciowa przerywa połączenie. W tej sytuacji połączenie klienta z interfejsem sprzężenia zwrotnego działa dobrze, ale nie z interfejsem domowym / publicznym.

Mam nadzieję że to pomoże.


4 dla odpowiedzi nr 3

Aby udowodnić, który komponent zawodzi, monitorowałbym komunikację TCP / IP za pomocą wireshark i spójrz, kto faktycznie zamyka port, mogą również mieć znaczenie limity czasu.


3 dla odpowiedzi № 4

The java.net.SocketException jest generowany, gdy wystąpi błąd podczas tworzenia lub uzyskiwania dostępu gniazdo (Jak na przykład TCP). Zwykle może to być spowodowane zakończeniem połączenia przez serwer (bez jego prawidłowego zamknięcia), więc przed uzyskaniem pełnej odpowiedzi. W większości przypadków może to być spowodowane problemem z przekroczeniem limitu czasu (np. Odpowiedź zajmuje zbyt dużo czasu lub serwer jest przeciążony żądaniami) lub klient wysłał SYN, ale nie otrzymał ACK (potwierdzenie zakończenia połączenia) W przypadku problemów z przekroczeniem limitu czasu można rozważyć zwiększenie wartości limitu czasu.

Wyjątek gniazda zwykle zawiera określony komunikat szczegółowy dotyczący problemu.

Przykład szczegółowych wiadomości:

  • Oprogramowanie spowodowało przerwanie połączenia: recv nie powiodło się.

    Błąd wskazuje na próbę wysłania wiadomości i połączenie zostało przerwane przez serwer. Jeśli tak się stało podczas łączenia z bazą danych, może to być związane z używaniem niekompatybilny sterownik Connector / J JDBC.

    Możliwe rozwiązanie: Upewnij się, że masz odpowiednie biblioteki / sterowniki w CLASSPATH.

  • Oprogramowanie spowodowało przerwanie połączenia: połącz.

    Może się to zdarzyć, gdy wystąpi problem z połączeniem z pilotem. Na przykład z powodu odrzucenia przez program antywirusowy żądań zdalnej poczty.

    Możliwe rozwiązanie: sprawdź, czy usługa skanowania antywirusowego blokuje port dla wychodzących żądań połączeń.

  • Oprogramowanie spowodowało przerwanie połączenia: błąd zapisu gniazda.

    Możliwe rozwiązanie: upewnij się, że „zapisujesz poprawną długość bajtów w strumieniu. Więc dokładnie sprawdź, co wysyłasz. Zobacz wątek.

  • Resetowanie połączenia przez peer: błąd zapisu gniazda / Połączenie przerwane przez peer: błąd zapisu gniazda

    Aplikacja nie sprawdziła, czy przekroczono limit czasu połączenia podtrzymywanego po stronie serwera.

    Możliwe rozwiązanie: Przed odczytem połączenia upewnij się, że HttpClient ma wartość inną niż null.E13222_01

  • Resetowanie połączenia przez peera.

    Połączenie zostało zakończone przez peer (serwer).

  • Resetowanie połączenia.

    Połączenie zostało zakończone przez klienta lub zamknięte przez serwer na końcu połączenia z powodu żądania z żądaniem.

    Widzieć: Co powoduje mój wyjątek java.net.SocketException: reset połączenia?


2 dla odpowiedzi № 5

Czy sprawdziłeś kod źródłowy Tomcat? i źródło JVM? To może ci pomóc.

Myślę, że twoje ogólne myślenie jest dobre. Spodziewałbym się ConnectException w scenariuszu, w którym nie można było się połączyć. Powyższe wygląda na bardzo zależne od klienta.


2 dla odpowiedzi № 6

Dla każdego, kto używa prostych programów Client Server i otrzymuje ten błąd, jest to problem z niezamkniętymi (lub zamkniętymi do wczesnych) strumieniami wejściowymi lub wyjściowymi.


1 dla odpowiedzi № 7

Miałem do czynienia z tym samym problemem.
Często Ten rodzaj błędu występuje, ponieważ klient zamknął połączenie i serwer nadal próbuje pisać na tym kliencie.
Upewnij się więc, że twój klient ma otwarte połączenie, dopóki serwer nie skończy ze swoim strumieniem wyjściowym.
I jeszcze jedno, nie zapomnij zamknij strumień wejściowy i wyjściowy.

Mam nadzieję że to pomoże.
A jeśli nadal masz do czynienia z problemem, opisz go szczegółowo tutaj.


0 dla odpowiedzi № 8

Ten błąd przydarzył mi się podczas testowania mojej usługi mydła w kliencie SoapUI. Zasadniczo próbowałem uzyskać bardzo duży komunikat (> 500 kb) i SoapUI zamknął połączenie przed upływem limitu czasu.

W SoapUI przejdź do:

Plik -> Preferencje - Limit czasu gniazda (ms)

... i dużą wartość, na przykład 180000 (3 minuty), nie będzie to idealne rozwiązanie problemu, ponieważ plik jest w rzeczywistości zbyt duży, ale przynajmniej otrzymasz odpowiedź.


0 dla odpowiedzi № 9

W moim przypadku błąd był następujący:

java.net.SocketException: Software caused connection abort: recv failed

Został odebrany w zaćmieniu podczas debugowania javaaplikacja uzyskująca dostęp do bazy danych H2. Źródłem błędu było to, że początkowo otworzyłem bazę danych za pomocą SQuirreL, aby ręcznie sprawdzić integralność. Użyłem flagi, aby umożliwić wiele połączeń z tym samym DB (tj. AUTO_SERVER=TRUE), więc nie było problemu z połączeniem się z bazą danych z Java.

Błąd pojawił się, gdy po chwili - todługi proces Java - postanowiłem zamknąć SQuirreL w celu uwolnienia zasobów. Wygląda na to, że SQuirreL był tym, który „był właścicielem” instancji serwera DB i że został zamknięty za pomocą połączenia SQuirreL.

Ponowne uruchomienie aplikacji Java nie spowodowało ponownego wystąpienia błędu.

config

  • System Windows 7
  • Eclipse Kepler
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192

-1 dla odpowiedzi № 10

Mój serwer zgłaszał ten wyjątek w ciągu 2 dni i rozwiązałem go, przenosząc funkcję rozłączania za pomocą:

outputStream.close();
inputStream.close();
Client.close();

Do końca wątku z listą. jeśli to pomoże komukolwiek.


-1 dla odpowiedzi № 11

W opisanej poniżej sytuacji strona klienta zgłosi taki wyjątek:

Serwer jest proszony o uwierzytelnienie klientacertyfikat, ale klient dostarcza certyfikat, którego Rozszerzone użycie klucza nie obsługuje uwierzytelniania klienta, więc serwer nie akceptuje certyfikatu klienta, a następnie zamyka połączenie.


-3 dla odpowiedzi № 12

Napotkałem ten sam problem z wireMock podczas wyśmiewania pozostałych wywołań API. Wcześniej definiowałem serwer w ten sposób:

WireMockServer wireMockServer = null;

Ale należy to zdefiniować jak pokazano poniżej:

@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);