จากคำถามล่าสุดฉันสงสัยว่าเหตุใดจึงเป็นไปไม่ได้ใน Java โดยไม่ต้องพยายามอ่าน / เขียนบนซ็อกเก็ต TCP เพื่อตรวจสอบว่าเพียร์ปิดซ็อกเก็ตอย่างสง่างาม? ดูเหมือนว่าจะเป็นเช่นนี้ไม่ว่าจะใช้พรี NIO Socket
หรือ NIO SocketChannel
ก็ตาม
เมื่อเพียร์ปิดการเชื่อมต่อ TCP อย่างสง่างาม TCP สแต็กทั้งสองด้านของการเชื่อมต่อจะรู้เกี่ยวกับข้อเท็จจริง ฝั่งเซิร์ฟเวอร์ (หนึ่งที่บำเพ็ญปิดระบบ) สิ้นสุดลงในรัฐFIN_WAIT2
ในขณะที่ฝั่งไคลเอ็นต์ (หนึ่งที่ไม่ชัดเจนตอบสนองต่อการปิดเครื่อง) CLOSE_WAIT
จะสิ้นสุดลงในรัฐ เหตุใดจึงไม่มีเมธอดในSocket
หรือSocketChannel
ที่สามารถสอบถามสแต็ก TCP เพื่อดูว่าการเชื่อมต่อ TCP พื้นฐานถูกยุติหรือไม่ สแต็ก TCP ไม่ให้ข้อมูลสถานะดังกล่าวหรือไม่? หรือเป็นการตัดสินใจออกแบบเพื่อหลีกเลี่ยงการโทรเข้าเคอร์เนลที่มีราคาแพง?
ด้วยความช่วยเหลือของผู้ใช้ที่ได้โพสต์คำตอบสำหรับคำถามนี้แล้วฉันคิดว่าฉันเห็นว่าปัญหาอาจมาจากไหน ด้านที่ไม่ได้ปิดการเชื่อมต่ออย่างชัดเจนจะสิ้นสุดลงในสถานะ TCP CLOSE_WAIT
หมายความว่าการเชื่อมต่ออยู่ระหว่างการปิดระบบและรอให้ฝั่งนั้นออกการCLOSE
ดำเนินการของตัวเอง ฉันคิดว่ามันยุติธรรมพอที่isConnected
จะส่งคืนtrue
และisClosed
คืนสินค้าfalse
แต่ทำไมถึงไม่มีบางอย่างเช่นisClosing
?
ด้านล่างนี้คือคลาสทดสอบที่ใช้ซ็อกเก็ต pre-NIO แต่จะได้ผลลัพธ์ที่เหมือนกันโดยใช้ 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);
}
}
เมื่อไคลเอนต์ทดสอบเชื่อมต่อกับเซิร์ฟเวอร์ทดสอบเอาต์พุตจะยังคงไม่เปลี่ยนแปลงแม้ว่าเซิร์ฟเวอร์จะเริ่มการปิดการเชื่อมต่อ:
connected: true, closed: false
connected: true, closed: false
...