Di utas utama saya, saya memiliki while(listening)
loop yang memanggil accept()
objek ServerSocket saya, kemudian memulai utas klien baru dan menambahkannya ke Koleksi ketika klien baru diterima.
Saya juga memiliki utas Admin yang ingin saya gunakan untuk mengeluarkan perintah, seperti 'keluar', yang akan menyebabkan semua utas klien dimatikan, matikan sendiri, dan matikan utas utama, dengan memutar mendengarkan false.
Namun, accept()
panggilan dalam while(listening)
loop blok, dan sepertinya tidak ada cara untuk menghentikannya, sehingga kondisi sementara tidak dapat diperiksa lagi dan program tidak dapat keluar!
Apakah ada cara yang lebih baik untuk melakukan ini? Atau beberapa cara untuk mengganggu metode pemblokiran?
java
networking
blocking
interrupt
lukeo05
sumber
sumber
Jawaban:
Anda dapat menelepon
close()
dari utas lainnya, danaccept()
panggilan itu akan melempar aSocketException
.sumber
close()
, maksud saya itu akan membuang pengecualian untuk melakukannya, jadi apakah ada cara lain (yang tidak membuang pengecualian, juga tidak berdasarkan batas waktu) untuk berhenti mendengarkan permintaan?readLine()
kemudian akan mengembalikan nol dan operasi penutupan normal yang seharusnya sudah ada di thread akan terjadi.Setel batas waktu aktif
accept()
, maka panggilan akan menghentikan pemblokiran setelah waktu yang ditentukan:http://docs.oracle.com/javase/7/docs/api/java/net/SocketOptions.html#SO_TIMEOUT
sumber
Menyerukan
close()
padaServerSocket
pilihan sebuah?http://java.sun.com/j2se/6/docs/api/java/net/ServerSocket.html#close%28%29
sumber
Anda bisa membuat soket "void" untuk break serversocket.accept ()
Sisi server
Metode untuk memutus siklus server
sumber
Alasan
ServerSocket.close()
melempar pengecualian adalah karena Anda memilikioutputstream
atauinputstream
melekat pada soket itu. Anda dapat menghindari pengecualian ini dengan aman dengan terlebih dahulu menutup aliran input dan output. Kemudian coba tutupServerSocket
. Berikut ini sebuah contoh:Anda dapat memanggil metode ini untuk menutup soket apa pun dari mana saja tanpa mendapatkan pengecualian.
sumber
ServerSocket
tetapi ke aSocket
dan kita berbicara tentang menutupServerSocket
bukanSocket
, sehinggaServerSocket
dapat ditutup tanpa menutupSocket
stream a.Gunakan serverSocket.setSoTimeout (timeoutInMillis) .
sumber
OK, saya membuat ini bekerja dengan cara yang menjawab pertanyaan OP lebih langsung.
Terus baca melewati jawaban singkat untuk contoh Utas tentang bagaimana saya menggunakan ini.
Jawaban singkat:
Contoh dunia nyata:
Dalam contoh ini, saya memiliki ServerSocket yang menunggu koneksi di dalam sebuah Thread. Ketika saya menutup aplikasi, saya ingin mematikan utas (lebih khusus, soket) dengan cara yang bersih sebelum saya menutup aplikasi, jadi saya menggunakan .setSoTimeout () pada ServerSocket kemudian saya menggunakan interupsi yang dilemparkan setelah batas waktu untuk memeriksa dan melihat apakah orang tua mencoba untuk mematikan utas. Jika demikian, maka saya mengatur tutup soket, kemudian mengatur bendera yang menunjukkan bahwa thread selesai, kemudian saya keluar dari loop Threads yang mengembalikan nol.
Kemudian, di kelas Kontroler saya ... (Saya hanya akan menunjukkan kode yang relevan, pijat ke dalam kode Anda sendiri sesuai kebutuhan)
Saya harap ini membantu seseorang di jalan.
sumber
Hal lain yang dapat Anda coba adalah pembersih, adalah memeriksa tanda pada loop terima, dan kemudian ketika admin Anda ingin mematikan pemblokiran utas pada tanda terima, atur tanda (buat amankan utas) dan kemudian buat soket klien koneksi ke soket mendengarkan. Penerimaan akan berhenti memblokir dan mengembalikan soket baru. Anda dapat menemukan beberapa hal protokol sederhana yang memberitahu utas pendengar untuk keluar dari utas dengan bersih. Dan kemudian tutup soket di sisi klien. Tidak ada pengecualian, jauh lebih bersih.
sumber