A kadar takip ettikçe son soruya , bunun soket incelikle eş tarafından kapalı olduğunu tespit etmek için, bir TCP soket üzerinde okuma / yazma girişiminde olmadan, Java imkansızdır neden acaba? Ön NIO Socket
veya NIO kullanılıp kullanılmadığına bakılmaksızın durum böyle görünüyor SocketChannel
.
Bir eş, bir TCP bağlantısını incelikle kapattığında, TCP, bağlantının her iki tarafındaki yığınları gerçeği bilir. Sunucu tarafı (kapatmayı başlatan) durumda biterken FIN_WAIT2
, istemci tarafı (kapatmaya açık bir şekilde yanıt vermeyen) durumda sona erer CLOSE_WAIT
. Neden bir yöntem yoktur Socket
ya da SocketChannel
altta yatan bir TCP bağlantı sonlandırıldı olup olmadığını görmek için TCP yığını sorgulayabilir? TCP yığını böyle bir durum bilgisi sağlamıyor mu? Yoksa çekirdeğe yapılan maliyetli bir çağrıyı önlemek için bir tasarım kararı mı?
Bu soruya daha önce bazı cevaplar göndermiş olan kullanıcıların yardımıyla, sorunun nereden kaynaklanıyor olabileceğini düşünüyorum. Bağlantıyı açıkça kapatmayan taraf TCP durumunda sona erer, CLOSE_WAIT
bu da bağlantının kapanma sürecinde olduğu ve tarafın kendi CLOSE
işlemini gerçekleştirmesini bekler . O 's adil yeterince varsayalım isConnected
döner true
ve isClosed
döner false
, ama neden böyle orada bir şey değildir isClosing
?
NIO öncesi soketleri kullanan test sınıfları aşağıdadır. Ancak aynı sonuçlar NIO kullanılarak elde edilir.
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);
}
}
Test istemcisi test sunucusuna bağlandığında, sunucu bağlantıyı kapattıktan sonra bile çıktı değişmeden kalır:
connected: true, closed: false
connected: true, closed: false
...