Apa perbedaan antara koneksi dan batas waktu baca untuk soket?

180

3 pertanyaan:

  1. Apa perbedaan antara koneksi dan batas waktu baca untuk soket?

  2. Apa arti batas waktu koneksi diatur ke "tak terbatas"? Dalam situasi apa ia bisa tetap dalam infinitive loop? dan apa yang dapat memicu bahwa infinity-loop mati?

  3. Apa artinya batas waktu baca diatur ke "tak terbatas"? Dalam situasi apa ia bisa tetap dalam infinitive loop? dan apa yang dapat memicu bahwa infinity-loop mati?

corgrath
sumber

Jawaban:

227

1) Apa perbedaan antara koneksi dan batas waktu baca untuk soket?

Timeout koneksi adalah timeout dalam membuat koneksi awal; yaitu menyelesaikan handshake koneksi TCP. Batas waktu baca adalah batas waktu menunggu untuk membaca data 1 . Khususnya, jika server gagal mengirim byte <timeout> detik setelah byte terakhir, kesalahan batas waktu baca akan dinaikkan.

2) Apa artinya batas waktu koneksi diatur ke "tak terbatas"? Dalam situasi apa ia bisa tetap dalam infinitive loop? dan apa yang dapat memicu bahwa infinity-loop mati?

Ini berarti bahwa upaya koneksi berpotensi memblokir selamanya. Tidak ada loop tanpa batas, tetapi upaya untuk terhubung dapat diblokir oleh utas lain yang menutup soket. ( Thread.interrupt()Panggilan juga dapat melakukan trik ... tidak yakin.)

3) Apa yang dimaksud dengan batas waktu baca yang diatur ke "tak terbatas"? Dalam situasi apa ia bisa tetap berada dalam satu lingkaran tanpa batas? Apa yang bisa memicu loop tak terbatas itu berakhir?

Ini berarti bahwa panggilan ke readpada aliran soket dapat memblokir selamanya. Sekali lagi tidak ada loop tak terbatas, tetapi readdapat diblokir oleh Thread.interrupt()panggilan, menutup soket, dan (tentu saja) ujung lainnya mengirim data atau menutup koneksi.


1 - Ini bukan ... seperti yang dipikirkan oleh seorang komentator ... batas waktu berapa lama sebuah soket dapat dibuka, atau diam.

Stephen C
sumber
8

Ini adalah nilai batas waktu yang diberlakukan oleh JVM untuk pembuatan koneksi TCP dan menunggu pembacaan data dari soket.

Jika nilainya diatur hingga tak terbatas, Anda tidak akan menunggu selamanya. Ini berarti JVM tidak memiliki batas waktu dan OS akan bertanggung jawab atas semua batas waktu. Namun, batas waktu pada OS mungkin sangat panjang. Pada beberapa jaringan yang lambat, saya telah melihat batas waktu selama 6 menit.

Bahkan jika Anda menetapkan nilai batas waktu untuk soket, itu mungkin tidak berfungsi jika batas waktu terjadi dalam kode asli. Kami dapat mereproduksi masalah di Linux dengan menghubungkan ke host yang diblokir oleh firewall atau mencabut kabel saat sakelar.

Satu-satunya pendekatan yang aman untuk menangani batas waktu TCP adalah dengan menjalankan kode koneksi di utas yang berbeda dan menyela utas saat terlalu lama.

ZZ Coder
sumber
"Jika nilainya diatur hingga tak terbatas, Anda tidak akan menunggu selamanya." Selama ini bukan tentang diskusi tentang makna "tak terbatas", itu pasti bisa terjadi bahwa Anda menunggu sangat lama. Kami punya kasus di sini, di mana HttpURLConnection.getResponseCode()tergantung untuk apprx. seminggu sampai kami memulai kembali prosesnya. Jelas tidak ada batas waktu yang ditetapkan pada sisi JVM dan juga tidak ada batas waktu di sisi Linux OS.
Tom Fink
Paragraf terakhir tidak benar. Sambungan akan habis setelah paling banyak satu menit. Utas terpisah sama sekali tidak perlu. Anda tentu dapat membaca yang berjalan selamanya jika tidak ada data. Namun Javadoc salah tentang batas waktu koneksi default menjadi tak terbatas. Bukan itu.
Marquis of Lorne
1
@comeGetSome. Itu tidak benar. Anda dapat mematikan soket untuk input. Itu akan menyebabkan pembacaan yang diblokir menemui ujung aliran.
Marquis of Lorne
@comeGetSome: Saya harus menerapkan ini menggunakan utas yang memegang referensi ke koneksi URL HTTP terbuka. Ketika utas tersebut menutup koneksi, utas lainnya melempar "java.net.SocketException: Socket closed". Terima kasih bug JDK-8075484 untuk membuat saya melakukan itu!
fmcato
@comeGetSome Pasti Anda bisa menelepon Socket.shutdownInput()tanpa memegang tangan Anda? NB Timeout ini diberlakukan oleh TCP, bukan JVM.
Marquis of Lorne