Офіційні причини "Перервано з’єднання через програмне забезпечення: помилка запису сокета"


157

З огляду на цей фрагмент відстеження стека

Викликано: java.net.SocketException: Програмне забезпечення, пов’язане з перериванням зв'язку: помилка запису сокета
 на java.net.SocketOutputStream.socketWrite0 (Native Method)

Я намагався відповісти на наступні питання:

  1. Який код кидає цей виняток? (JVM? / Tomcat? / Мій код?)
  2. Що спричиняє викид цього винятку?

Щодо №1:

Джерело JVM Sun не містить цього точного повідомлення, але я вважаю, що текст, викликаний програмним забезпеченням, з'єднання перервано: помилка запису сокета - це від нативної реалізації SocketOutputStream:

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

Щодо №2

Я гадаю, що це викликано, коли клієнт припинив з'єднання, перш ніж отримати повну відповідь (наприклад, надіслав запит, але перш ніж отримати повну відповідь, він закрився / припинено / офлайн)

Запитання:

  1. Чи правильні вище припущення (№1 та №2)?
  2. Чи можна це відрізнити від ситуації: "не вдалося написати клієнту через помилку мережі на стороні сервера "? чи це відображатиме те саме повідомлення про помилку?
  3. І найважливіше: чи існує офіційний документ (наприклад, від Sun), що вказує вище?

Мені потрібно мати доказ того, що цей слід стека - це "вина" клієнта сокету, і сервер міг би зробити це, щоб цього уникнути. .


У мене ця проблема при скасуванні завантаження з Firefox
koppor

Ей, Еран, я також отримую цей виняток під час надсилання / написання ( outs.write(audioBytes);) byte[]в OutputStream. Коли звук лежить і під час відтворення, якщо користувач натискає будь-яке інше меню (яке надсилає запит на сервер), я отримав таку ж помилку на консолі. так чи безпечно ігнорувати цей виняток?
Amogh

1
@Amogh - Здається, так, так. В основному з того, що описують відповіді, це специфічна помилка для Windows, але я припускаю, що в Linux ви отримаєте той самий виняток лише з іншим формулюванням ... (Мої миряни розуміють це в основному, що це викликано при надсиланні через розетку до якогось віддаленого місця X і X відключилися посередині, але я впевнений, що це не найточніший спосіб описати це)
Еран Медан

1
Для мене це сталося, коли сервер бази даних був перезапущений, і програма все ще намагалася здійснити запит, використовуючи раніше відкриті з'єднання. Не впевнений, чому вони не були оновлені, оскільки ми використовуємо групування на основі DBCP. Але перезапуск програми усунув проблему.
Kshitiz Sharma

Відповіді:


55

Ця помилка може виникнути, коли система локальної мережі припиняє з'єднання, наприклад, коли WinSock закриває встановлене з'єднання після відмови повторної передачі даних (одержувач ніколи не визнає дані, що надсилаються в сокет потоку даних).

Дивіться цю статтю MSDN . Див. Також Деякі відомості про "Перервано з’єднання через програмне забезпечення" .



3
@MatGessel Ця стаття просто повторює плутанину і додає деякі свої. WSAECONNABORTED - це код помилки Вінсока, тому не може бути пояснення Берклі для цього. Описана ситуація щодо HTTP-сервера створювала б ECONNRESET, а не WSAECONNABORTED.
Маркіз Лорнський

@EJP, я також отримую цей виняток під час надсилання / запису (outs.write (audioBytes);) байт [] в OutputStream. Коли звук лежить і під час відтворення, якщо користувач натискає будь-яке інше меню (яке надсилає запит на сервер), я отримав таку ж помилку на консолі. так чи безпечно ігнорувати цей виняток?
Amogh

1
@rustyx Усі три цитовані тут джерела стверджують, що воно виробляється через збої ACK. Якщо у вас є джерело власної претензії, будь ласка, цитуйте це.
Маркіз Лорнський

2
Це не справжня відповідь, оскільки вона не дає вам інформації для подальшого продовження проблеми. Відповідь тут в основному "щось погане трапилося в мережі". Було б дуже корисно зрозуміти, які подальші журнали та інші записи про діяльність можуть дати мені змогу точно визначити основну проблему.
Дерек Беннетт

11

The java.net.SocketExceptionвикидається, коли виникає помилка створення або доступу до сокета (наприклад, TCP ). Зазвичай це може бути викликано, коли сервер припинив з'єднання (не належним чином закривши його), тому перш ніж отримати повну відповідь. У більшості випадків це може бути викликано проблемою таймауту (наприклад, відповідь займає занадто багато часу або сервер перевантажений запитами), або клієнт надіслав SYN, але він не отримав ACK (підтвердження припинення з'єднання) . Щодо проблем із тимчасовим очікуванням, ви можете розглянути можливість збільшення таймауту.

Виняток Socket зазвичай постачається із вказаним детальним повідомленням про проблему.

Приклад детальних повідомлень:

  • Перервано з’єднання з програмним забезпеченням: невдалий recv.

    Помилка вказує на спробу відправити повідомлення, і з'єднання перервано вашим сервером. Якщо це сталося під час підключення до бази даних, це може бути пов’язано з використанням несумісного драйвера Connector / J JDBC .

    Можливе рішення: Переконайтеся, що у вашому CLASSPATH належні бібліотеки / драйвери.

  • Підключення через програмне забезпечення перервано: підключити.

    Це може статися, коли є проблема підключення до пульта. Наприклад, через перевірку вірусом відхилення запитів на віддалену пошту .

    Можливе рішення: Перевірте службу сканування вірусів, чи блокує порт вихідні запити на з'єднання.

  • Перервано з’єднання через програмне забезпечення: помилка запису сокета.

    Можливе рішення: Переконайтеся, що ви записуєте правильну довжину байтів у потік. Тому двічі перевірте, що ви надсилаєте. Дивіться цю нитку .

  • Скидання з'єднання одноранговим: помилка запису сокета / З'єднання перервано рівним рівнем: помилка запису сокета

    Додаток не перевіряв, чи збережено збережене з'єднання на стороні сервера.

    Можливе рішення: Переконайтеся, що HttpClient не є нульовим, перш ніж читати з з'єднання. E13222_01

  • Підключення скинуто іншим комп'ютером.

    З'єднання було припинено одноранговим сервером (сервером).

  • Скидання з'єднання.

    З'єднання було або припинено клієнтом, або закрите серверним кінцем з'єднання через запит із запитом.

    Дивіться: Що спричиняє мій java.net.SocketException: скидання з’єднання?


Лише один із цих 6 пунктів насправді відповідає на питання неправильно. Кілька інших також є невірними. Додаток не може "перевірити, чи було встановлено тимчасове з'єднання на стороні сервера". HttpClientІстота nullне може викликати SocketException. Якщо записати правильну довжину в потік, також немає.
Маркіз Лорн

9

Я бачив це найчастіше, коли корпоративний брандмауер на робочій станції / ноутбуці заважає, це вбиває зв’язок.

напр. У мене є серверний процес і клієнтський процес на одній машині. Сервер прослуховує всі інтерфейси (0.0.0.0), і клієнт намагається підключитися до загальнодоступного / домашнього інтерфейсу (зауважте, не інтерфейс петлі 127.0.0.1).

Якщо у машини відключена мережа (наприклад, вимкнено wifi), то з'єднання формується. Якщо машина підключена до корпоративної мережі (безпосередньо або vpn), то з'єднання формується.

Однак якщо машина підключена до загальнодоступного Wi-Fi (або домашньої мережі), то брандмауер знищує з'єднання. У цій ситуації підключення клієнта до інтерфейсу зворотного зв’язку працює добре, тільки не до домашнього / загальнодоступного інтерфейсу.

Сподіваюся, це допомагає.


3
Брандмауери перешкоджають з'єднанню. Питання стосується скидання наявного з'єднання.
Маркіз Лорн

4

Щоб довести, який компонент не вдається, я би моніторив TCP / IP-зв’язок за допомогою проводки і дивився, хто точно закриває порт, також можуть бути актуальними тайм-аути.


Ніхто не закриває порт. Операційна система припиняє з'єднання.
Маркіз Лорн

@EJP Я бачив, як це відбувається, коли перевантажується і не вистачає пам'яті. Я не впевнений, що саме ОС закриває з'єднання, але JVM стає диким.
Zee

1
@Zee Існує різниця між закриттям порту, який у Wireshark видно як FIN, і припиненням з'єднання, яке не є.
Маркіз Лорнський

2

Ви перевірили вихідний код Tomcat та джерело JVM? Це може вам більше допомогти.

Я думаю, що ваше загальне мислення добре. Я б очікував, що ConnectExceptionв сценарії ви не можете підключитися Згадане вище виглядає так, як це орієнтоване на клієнтів


3
Так, я перевірив. Джерела Tomcat не містили перестановки вироку, дякую.
Еран Медан

1
Ні, він не перевіряв джерело Tomcat І джерело JVM.
Стівен С

Або якщо він перевірив джерело JVM, він не перевірив усе це.
Стівен С

1
@Ehrann - рядок повідомлень, швидше за все, у рідних джерелах. Але також слід перевірити журнал подій. ІМО, остання, ймовірно, буде більш інформативною.
Стівен C

6
Цей рядок повідомлень фактично надходить з операційної системи.
Маркіз Лорн

2

Для тих, хто використовує прості програми клієнтського сервера та отримує цю помилку, це проблема незакритих (або закритих на ранніх) потоків введення чи виводу.


2
Ні, це не так. Це призведе до витоку розетки, що в кінцевому підсумку призведе до виснаження ФД.
Маркіз Лорнський

0

Я стикався з тим же питанням.
Зазвичай ця помилка виникає через те, що клієнт закрив своє з'єднання і сервер все ще намагається писати на цьому клієнті.
Тому переконайтеся, що ваш клієнт відкрито підключення до тих пір, поки сервер не виконає його вихідний потік.
І ще одне - не забув закрити вхідний і вихідний потік.

Сподіваюся, це допомагає.
І якщо ви все ще стикаєтеся з проблемою, то коротко опишіть тут свою проблему детально.


3
@BhavinChhatrola Ні, неправильна відповідь. Описана ситуація призводить до "скидання з’єднання одночасно", а не до помилки у питанні.
Маркіз Лорн

0

Ця помилка трапилася зі мною під час тестування сервісу мила з клієнтом SoapUI, в основному я намагався отримати дуже велике повідомлення (> 500 кбіт), і SoapUI закрив з'єднання за таймаутом.

На SoapUI перейдіть до:

Файл -> Параметри - Час очікування розетки (мс)

... і поставивши велике значення, наприклад, 180000 (3 хвилини), це не буде ідеальним виправленням вашої проблеми, оскільки файл насправді великий, але принаймні у вас буде відповідь.


0

Закрите з'єднання в іншому клієнті

У моєму випадку помилка була:

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

Він був отриманий у затемненні під час налагодження програми Java, що отримує доступ до бази даних H2. Джерелом помилки було те, що я спочатку відкрив базу даних з SQuirreL, щоб перевірити цілісність вручну. Я використовував прапор, щоб увімкнути кілька підключень до однієї БД (тобто AUTO_SERVER=TRUE), тому не було проблем з підключенням до БД від Java.

Помилка з'явилася, коли через деякий час - це довгий процес Java - я вирішив закрити SQuirreL для вільних ресурсів. Схоже, SQuirreL був "власником" екземпляра сервера БД, і що він був закритий підключенням SQuirreL.

Перезапуск програми Java знову не призвів до помилки.

конфігурація

  • Windows 7
  • Затемнення Кеплера
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192

0

У моєму випадку я розробив клієнт та серверну сторону, і у мене є виняток:

Причина: аргументи аргументованих помилок; Вкладений виняток: java.net.SocketException: програмне забезпечення, пов’язане з програмним забезпеченням, перервано: помилка запису сокета

коли заняття у клієнта та сервера різні. Я не завантажую серверні класи (інтерфейси) на клієнт, я додаю ті самі файли в проект. Але шлях повинен бути точно таким же. Наприклад, у серверному проекті у мене є пакети java \ rmi \ services з деякими serviceInterface та реалізаціями, я повинен створити той самий пакет у проекті клієнта. Якщо я зміню його, наприклад, на java / rmi / server / services, я отримую вищевикладене виключення. Те саме виняток, якщо версія інтерфейсу відрізняється між клієнтом і сервером (навіть із випадково доданим порожнім рядком ... Я думаю, що Rmi робить своєрідний хеш-клас для перевірки версії ... Я не знаю ... Якби це могло допомогти ...


-1

Мій сервер кидав цей виняток за пропуск 2 дні, і я вирішив це, перемістивши функцію відключення за допомогою:

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

До кінця списку лістингу. якщо це комусь допоможе.


-1

У ситуації, поясненій нижче, сторона клієнта кине такий виняток:

Сервер просить підтвердити автентифікацію клієнтського сертифіката, але клієнт надає сертифікат, розширене використання якого не підтримує автентифікацію клієнта, тому сервер не приймає сертифікат клієнта, а потім він закриває з'єднання.


Ця відповідь невірна. У випадку, коли ви описуєте, SSLException буде кинуто.
президент Джеймс К. Полк

насправді це кидає SocketException так само, як у нинішньому питанні, я тестував
xiaoming

-1

ssl сторона клієнта викине такий виняток у нижченаведеній ситуації (Я протестував),:

сервер просить підтвердити автентифікацію клієнтського сертифіката, але клієнт надає сертифікат, який не використовує розширений ключ використання, підтримуючи автентифікацію клієнта.


-3

Я стикався з тією ж проблемою, що і з WireMock, знущаючись над іншими дзвінками API. Раніше я визначав сервер так:

WireMockServer wireMockServer = null;

Але його слід визначити так, як показано нижче:

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

Це спричинило б NullPointerExceptionне цю проблему.
Маркіз Лорн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.