Sebagai tindak lanjut dari pertanyaan terbaru , saya bertanya-tanya mengapa tidak mungkin di Java, tanpa mencoba membaca / menulis pada soket TCP, untuk mendeteksi bahwa soket telah ditutup dengan baik oleh rekan? Ini tampaknya menjadi kasus terlepas dari apakah seseorang menggunakan pra-NIO Socket
atau NIO SocketChannel
.
Ketika rekan dengan anggun menutup koneksi TCP, tumpukan TCP di kedua sisi koneksi mengetahui fakta tersebut. Sisi server (yang memulai penghentian) berakhir dalam status FIN_WAIT2
, sedangkan sisi klien (yang tidak secara eksplisit menanggapi pematian) berakhir dalam status CLOSE_WAIT
. Mengapa tidak ada metode Socket
atau SocketChannel
yang dapat menanyakan tumpukan TCP untuk melihat apakah koneksi TCP yang mendasari telah diakhiri? Apakah tumpukan TCP tidak memberikan informasi status seperti itu? Ataukah keputusan desain untuk menghindari panggilan yang mahal ke kernel?
Dengan bantuan pengguna yang telah memposting beberapa jawaban untuk pertanyaan ini, saya pikir saya melihat dari mana masalah itu mungkin berasal. Sisi yang tidak secara eksplisit menutup koneksi berakhir dalam status TCP yang CLOSE_WAIT
berarti bahwa koneksi sedang dalam proses mematikan dan menunggu sisi tersebut mengeluarkan operasinya sendiri CLOSE
. Saya kira cukup adil bahwa isConnected
pengembalian true
dan isClosed
pengembalian false
, tetapi mengapa tidak ada yang seperti itu isClosing
?
Di bawah ini adalah kelas pengujian yang menggunakan soket pra-NIO. Tetapi hasil yang identik diperoleh dengan menggunakan NIO.
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) throws Exception {
final ServerSocket ss = new ServerSocket(12345);
final Socket cs = ss.accept();
System.out.println("Accepted connection");
Thread.sleep(5000);
cs.close();
System.out.println("Closed connection");
ss.close();
Thread.sleep(100000);
}
}
import java.net.Socket;
public class MyClient {
public static void main(String[] args) throws Exception {
final Socket s = new Socket("localhost", 12345);
for (int i = 0; i < 10; i++) {
System.out.println("connected: " + s.isConnected() +
", closed: " + s.isClosed());
Thread.sleep(1000);
}
Thread.sleep(100000);
}
}
Saat klien uji terhubung ke server uji, hasilnya tetap tidak berubah bahkan setelah server memulai pemadaman koneksi:
connected: true, closed: false
connected: true, closed: false
...