Alasan resmi untuk “Perangkat lunak menyebabkan koneksi dibatalkan: kesalahan penulisan soket”

157

Diberikan cuplikan jejak tumpukan ini

Disebabkan oleh: java.net.SocketException: Perangkat lunak menyebabkan koneksi dibatalkan: kesalahan penulisan socket
 di java.net.SocketOutputStream.socketWrite0 (Metode Asli)

Saya mencoba menjawab pertanyaan-pertanyaan berikut:

  1. Kode apa yang melempar pengecualian ini? (JVM? / Tomcat? / Kode saya?)
  2. Apa yang menyebabkan pengecualian ini dilemparkan?

Mengenai # 1:

Sumber JVM Sun tidak mengandung pesan persis ini, tapi saya pikir Perangkat Lunak teks menyebabkan koneksi dibatalkan: kesalahan penulisan socket berasal dari implementasi asli SocketOutputStream:

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

Mengenai # 2

Dugaan saya adalah bahwa hal itu disebabkan ketika klien telah memutuskan koneksi, sebelum mendapatkan respon penuh (misalnya mengirim permintaan, tetapi sebelum mendapatkan respon penuh, ia ditutup / dihentikan / offline)

Pertanyaan:

  1. Apakah asumsi di atas benar (# 1 dan # 2)?
  2. Bisakah ini dibedakan dari situasi: "tidak bisa menulis ke klien, karena kesalahan jaringan di sisi server "? atau akankah itu membuat pesan kesalahan yang sama?
  3. Dan yang paling penting: Apakah ada dokumen resmi (misalnya dari Sun) yang menyatakan hal di atas?

Saya perlu memiliki bukti bahwa tumpukan jejak ini adalah "kesalahan" klien soket, dan tidak ada yang bisa dilakukan server untuk menghindarinya. (kecuali menangkap pengecualian, atau menggunakan SocketOutputStream non Sun JVM, meskipun keduanya tidak benar-benar menghindari fakta bahwa klien telah mengakhiri)

Eran Medan
sumber
Saya memiliki masalah ini ketika membatalkan unduhan dengan Firefox
koppor
Hai Eran, saya juga mendapatkan pengecualian ini saat mengirim / menulis ( outs.write(audioBytes);) byte[]ke OutputStream. Ketika audio plying dan saat diputar jika pengguna mengklik menu lain (yang mengirim permintaan server) saya mendapat kesalahan yang sama pada konsol. jadi apakah aman untuk mengabaikan pengecualian ini?
Amogh
1
@ Amogh - Sepertinya begitu, ya. Pada dasarnya dari apa yang dijelaskan oleh jawaban, ini adalah kesalahan khusus Windows, tetapi saya berasumsi di Linux Anda akan mendapatkan pengecualian yang sama hanya dengan kata-kata yang berbeda ... (Orang awam saya memahami hal ini pada dasarnya bahwa ini disebabkan ketika Anda mengirim melalui soket ke beberapa lokasi terpencil X dan X terputus di tengah, tapi saya yakin itu bukan cara yang paling akurat untuk menggambarkannya)
Eran Medan
1
Bagi saya ini terjadi ketika server database dihidupkan ulang dan aplikasi masih mencoba untuk query menggunakan koneksi yang sebelumnya dibuka. Tidak yakin mengapa ini tidak disegarkan karena kami menggunakan pengumpulan berdasarkan DBCP. Tetapi me-restart aplikasi memperbaiki masalah.
Kshitiz Sharma

Jawaban:

55

Kesalahan ini dapat terjadi ketika sistem jaringan lokal membatalkan koneksi, seperti ketika WinSock menutup koneksi yang dibuat setelah transmisi ulang gagal (penerima tidak pernah mengakui data yang dikirim pada soket datastream).

Lihat artikel MSDN ini . Lihat juga Beberapa informasi tentang 'Penghapusan koneksi yang disebabkan perangkat lunak' .

Marquis dari Lorne
sumber
3
@MatGessel Artikel itu hanya mengulang kebingungan, dan menambahkan beberapa sendiri. WSAECONNABORTED adalah kode kesalahan Winsock, jadi tidak mungkin ada penjelasan Berkeley untuk itu. Situasi yang dijelaskan tentang server HTTP akan menghasilkan ECONNRESET, bukan WSAECONNABORTED.
Marquis of Lorne
@ EJP, saya juga mendapatkan pengecualian ini saat mengirim / menulis (outs.write (audioBytes);) byte [] ke OutputStream. Ketika audio plying dan saat diputar jika pengguna mengklik menu lain (yang mengirim permintaan server) saya mendapat kesalahan yang sama pada konsol. jadi apakah aman untuk mengabaikan pengecualian ini?
Amogh
1
@ rustyx Ketiga sumber yang dikutip di sini menyatakan bahwa itu dihasilkan oleh kegagalan ACK. Jika Anda memiliki sumber untuk klaim Anda sendiri, harap sebutkan.
Marquis of Lorne
2
Ini bukan jawaban nyata karena tidak memberi Anda informasi untuk melanjutkan masalah lebih lanjut. Jawabannya di sini pada dasarnya adalah "sesuatu yang buruk terjadi pada jaringan". Akan sangat membantu untuk memahami apa catatan lebih lanjut dan catatan kegiatan lainnya yang memungkinkan saya untuk menunjukkan masalah yang mendasarinya.
Derek Bennett
11

Itu java.net.SocketExceptiondilemparkan ketika ada kesalahan membuat atau mengakses soket (seperti TCP ). Ini biasanya dapat disebabkan ketika server telah memutuskan koneksi (tanpa menutupnya dengan benar), jadi sebelum mendapatkan respon penuh Dalam kebanyakan kasus, ini dapat disebabkan oleh masalah batas waktu (mis. Respons membutuhkan waktu terlalu lama atau server dipenuhi dengan permintaan), atau klien mengirim SYN, tetapi tidak menerima ACK (pengakuan akan penghentian koneksi) . Untuk masalah batas waktu, Anda dapat mempertimbangkan untuk meningkatkan nilai batas waktu.

Pengecualian Socket biasanya datang dengan pesan detail yang ditentukan tentang masalah ini.

Contoh pesan terperinci:

  • Perangkat lunak menyebabkan pembatalan koneksi: gagal gagal.

    Kesalahan menunjukkan upaya untuk mengirim pesan dan koneksi telah dibatalkan oleh server Anda. Jika ini terjadi saat menghubungkan ke database, ini dapat dikaitkan dengan menggunakan driver Connector / J JDBC yang tidak kompatibel .

    Solusi yang mungkin: Pastikan Anda memiliki perpustakaan / driver yang tepat di CLASSPATH Anda.

  • Perangkat lunak yang menyebabkan koneksi dibatalkan: terhubung.

    Ini bisa terjadi ketika ada masalah untuk terhubung ke remote. Misalnya karena pemeriksa virus menolak permintaan surat jarak jauh .

    Solusi yang mungkin: Periksa layanan Pemindaian Virus apakah itu memblokir port untuk permintaan koneksi keluar.

  • Perangkat lunak menyebabkan koneksi dibatalkan: kesalahan penulisan soket.

    Solusi yang mungkin: Pastikan Anda menulis panjang byte yang benar ke arus. Jadi periksa ulang apa yang Anda kirim. Lihat utas ini .

  • Koneksi diatur ulang oleh rekan: kesalahan penulisan soket / Koneksi dibatalkan oleh rekan: kesalahan penulisan soket

    Aplikasi tidak memeriksa apakah koneksi tetap hidup telah kehabisan waktu di sisi server.

    Solusi yang mungkin: Pastikan bahwa HttpClient adalah non-null sebelum membaca dari koneksi. E13222_01

  • Koneksi sudah diputus.

    Koneksi telah diakhiri oleh peer (server).

  • Koneksi diatur ulang.

    Koneksi telah diakhiri oleh klien atau ditutup oleh server pada akhir koneksi karena permintaan dengan permintaan.

    Lihat: Apa yang menyebabkan java.net.SocketException saya: Koneksi reset?

kenorb
sumber
Hanya satu dari 6 poin ini yang benar-benar menjawab pertanyaan, salah. Beberapa yang lain juga salah. Aplikasi tidak dapat 'memeriksa apakah koneksi keep-live telah habis di sisi server.' The HttpClientmakhluk nulltidak mungkin menyebabkan SocketException. Tidak menulis panjang yang benar untuk streaming juga tidak.
Marquis of Lorne
9

Saya telah melihat ini paling sering ketika firewall perusahaan pada workstation / laptop menghalangi, itu membunuh koneksi.

misalnya. Saya memiliki proses server dan proses klien pada mesin yang sama. Server mendengarkan pada semua antarmuka (0.0.0.0) dan klien mencoba koneksi ke antarmuka publik / rumah (perhatikan bukan antarmuka loopback 127.0.0.1).

Jika mesin memiliki jaringan yang terputus (mis. Wifi dimatikan) maka koneksi terbentuk. Jika mesin terhubung ke jaringan perusahaan (langsung atau vpn) maka koneksi terbentuk.

Namun, jika mesin terhubung ke wifi publik (atau jaringan rumah) maka firewall akan mematikan koneksi. Dalam situasi ini menghubungkan klien ke antarmuka loopback berfungsi dengan baik, hanya saja tidak ke antarmuka rumah / publik.

Semoga ini membantu.

pengguna2028913
sumber
3
Firewall mencegah koneksi. Pertanyaannya adalah tentang mengatur ulang koneksi yang ada.
Marquis of Lorne
4

Untuk membuktikan komponen mana yang gagal saya akan memonitor komunikasi TCP / IP menggunakan wireshark dan lihat siapa yang menutup port secara aktif, juga timeout bisa relevan.

stacker
sumber
Tidak ada yang menutup port. Sistem operasi membatalkan koneksi.
Marquis of Lorne
@ EJP Saya pernah melihat ini terjadi ketika kelebihan beban dan kehabisan memori. Saya tidak yakin itu adalah OS yang menutup koneksi tetapi JVM menjadi liar.
Zee
1
@ Zee Ada perbedaan antara menutup port, yang terlihat sebagai FIN di Wireshark, dan batalkan koneksi, yang tidak.
Marquis of Lorne
2

Sudahkah Anda memeriksa kode sumber Tomcat dan sumber JVM? Itu mungkin memberi Anda lebih banyak bantuan.

Saya pikir pemikiran umum Anda baik. Saya harapkan ConnectExceptiondalam skenario yang Anda tidak dapat terhubung. Di atas terlihat sangat seperti itu didorong oleh klien.

Brian Agnew
sumber
3
Ya, saya sudah memeriksa. Sumber Tomcat tidak mengandung permutasi dari kalimat itu, terima kasih.
Eran Medan
1
Tidak, dia belum memeriksa sumber Tomcat DAN sumber JVM.
Stephen C
Atau jika dia telah memeriksa sumber JVM, dia belum memeriksa semuanya.
Stephen C
1
@Ehrann - string pesan kemungkinan besar ada di sumber asli. Tetapi Anda juga harus memeriksa log peristiwa. IMO, yang terakhir cenderung lebih informatif.
Stephen C
6
String pesan ini sebenarnya berasal dari sistem operasi.
Marquis of Lorne
2

Bagi siapa pun yang menggunakan program-program Server Klien sederhana dan mendapatkan kesalahan ini, ini merupakan masalah dari Input atau Output Stream yang tidak tertutup (lebih awal).

PRO_gramista
sumber
2
Bukan itu. Itu akan menyebabkan kebocoran soket, yang pada akhirnya akan menyebabkan kelelahan FD.
Marquis of Lorne
0

Saya menghadapi masalah yang sama.
Umumnya kesalahan semacam ini terjadi karena klien telah menutup koneksinya dan server masih mencoba untuk menulis pada klien itu.
Jadi pastikan klien Anda memiliki koneksi terbuka sampai server selesai dengan aliran outputnya.
Dan satu hal lagi, jangan lupa untuk menutup input dan output stream.

Semoga ini membantu.
Dan jika masih menghadapi masalah daripada menjelaskan masalah Anda di sini secara rinci.

Nirav Chhatrola
sumber
3
@ BhavinChhatrola Tidak, jawaban yang salah. Situasi yang dijelaskan menghasilkan 'koneksi reset by peer', bukan kesalahan dalam pertanyaan.
Marquis of Lorne
0

Kesalahan ini terjadi pada saya saat menguji layanan sabun saya dengan klien SoapUI, pada dasarnya saya mencoba untuk mendapatkan pesan yang sangat besar (> 500kb) dan SoapUI menutup koneksi dengan batas waktu.

Pada SoapUI, buka:

File -> Preferences - Socket Timeout (ms)

... dan beri nilai besar, seperti 180000 (3 menit), ini tidak akan menjadi perbaikan yang sempurna untuk masalah Anda karena file tersebut sebenarnya terlalu besar, tetapi setidaknya Anda akan mendapat respons.

Marco
sumber
0

Koneksi tertutup di klien lain

Dalam kasus saya, kesalahannya adalah:

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

Itu diterima dalam gerhana saat debugging aplikasi java mengakses database H2. Sumber kesalahannya adalah saya awalnya membuka database dengan SQuirreL untuk memeriksa integritas secara manual. Saya memang menggunakan flag untuk mengaktifkan beberapa koneksi ke DB yang sama (yaitu AUTO_SERVER=TRUE), jadi tidak ada masalah menghubungkan ke DB dari java.

Kesalahan muncul ketika, setelah beberapa saat - itu adalah proses java yang panjang - Saya memutuskan untuk menutup SQuirreL ke sumber daya gratis. Tampaknya seolah-olah SQuirreL adalah orang yang "memiliki" server DB dan dimatikan dengan koneksi SQuirreL.

Restart aplikasi Java tidak menghasilkan kesalahan lagi.

konfigurasi

  • Windows 7
  • Eclipse Kepler
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192
manuelvigarcia
sumber
0

Dalam kasus saya, saya mengembangkan sisi klien dan server, dan saya memiliki pengecualian:

Penyebab: argumen kesalahan marshalling; pengecualian bersarang adalah: java.net.SocketException: Perangkat lunak yang menyebabkan koneksi dibatalkan: kesalahan penulisan soket

ketika kelas di klien dan server berbeda. Saya tidak mengunduh kelas server (Antarmuka) pada klien, saya hanya menambahkan file yang sama dalam proyek. Tapi jalannya harus persis sama. Sebagai contoh, pada proyek server saya memiliki paket layanan java \ rmi \ dengan beberapa serviceInterface dan implementasi, saya harus membuat paket yang sama pada proyek klien. Jika saya mengubahnya dengan java / rmi / server / layanan misalnya, saya mendapatkan pengecualian di atas. Pengecualian yang sama jika versi antarmuka berbeda antara klien dan server (bahkan dengan baris kosong ditambahkan secara tidak sengaja ... Saya pikir rmi membuat semacam kelas untuk memeriksa versi ... Saya tidak tahu ... Jika bisa Tolong ...

Elloco
sumber
-1

Server saya melempar pengecualian ini dalam 2 hari berlalu dan saya menyelesaikannya dengan memindahkan fungsi pemutusan dengan:

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

Sampai akhir utas cantuman. apakah itu akan membantu siapa pun.

Sefi Erlich
sumber
-1

Dalam situasi yang dijelaskan di bawah ini, pihak klien akan melemparkan pengecualian seperti itu:

Server diminta untuk mengautentikasi sertifikat klien, tetapi klien memberikan sertifikat yang Penggunaan Kunci yang Diperpanjang tidak mendukung auth klien, sehingga server tidak menerima sertifikat klien, dan kemudian menutup koneksi.

Xiaoming
sumber
Jawaban ini salah. Dalam hal ini Anda menggambarkan SSLException akan dilempar.
Presiden James K. Polk
sebenarnya itu melempar SocketException seperti pertanyaan saat ini, saya telah menguji
Xiaoming
-1

sisi klien ssl akan melemparkan pengecualian seperti itu dalam situasi di bawah ini (Saya telah menguji),:

server diminta untuk mengautentikasi sertifikat klien, tetapi klien memberikan sertifikat yang Penggunaan Kunci Diperpanjang tidak mendukung auth klien.

Xiaoming
sumber
-3

Saya menghadapi masalah yang sama dengan wireMock saat mengejek panggilan API lainnya. Sebelumnya saya mendefinisikan server seperti ini:

WireMockServer wireMockServer = null;

Tetapi harus didefinisikan seperti yang ditunjukkan di bawah ini:

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);
Yallaling Goudar
sumber
Itu akan menyebabkan NullPointerException, bukan masalah ini.
Marquis of Lorne