সাম্প্রতিক একটি প্রশ্নের অনুসরণ হিসাবে , আমি অবাক হয়েছি যে টিসিপি সকেটে পড়ার / লেখার চেষ্টা না করে জাভাতে কেন অসম্ভব, সনাক্ত করতে পারেন যে সকেটটি পিয়ারের দ্বারা নিখুঁতভাবে বন্ধ করা হয়েছে? এটি প্রাক-এনআইও Socket
বা এনআইও ব্যবহার করে কিনা তা বিবেচনা না করেই এটি কেস বলে মনে হচ্ছে SocketChannel
।
যখন কোনও পিয়ার দয়া করে কোনও টিসিপি সংযোগ বন্ধ করে দেয়, সংযোগের উভয় পক্ষের টিসিপি স্ট্যাকগুলি সত্যটি জানে। সার্ভার-সাইড (এক যে শাটডাউন শুরু করে) রাজ্যে শেষ হয় FIN_WAIT2
, যেখানে ক্লায়েন্ট-সাইড (যেটি শাটডাউনটিতে স্পষ্টভাবে সাড়া দেয় না) রাজ্যে শেষ হয় CLOSE_WAIT
। অন্তর্নিহিত টিসিপি সংযোগটি বন্ধ হয়ে গেছে কিনা তা দেখার জন্য কেন এমন কোনও পদ্ধতি নেই Socket
বা SocketChannel
যে টিসিপি স্ট্যাকটি জিজ্ঞাসা করতে পারে? এটি কি টিসিপি স্ট্যাকের মতো স্থিতির তথ্য সরবরাহ করে না? বা কার্নেলের মধ্যে ব্যয়বহুল কল এড়াতে এটি কোনও ডিজাইনের সিদ্ধান্ত?
ইতিমধ্যে এই প্রশ্নের কিছু উত্তর পোস্ট করা ব্যবহারকারীদের সহায়তায়, আমি মনে করি যে আমি দেখছি সমস্যাটি কোথা থেকে আসছে। যে পক্ষটি স্পষ্টভাবে সংযোগটি বন্ধ করে দেয় না সেটি টিসিপি অবস্থায় শেষ হয় CLOSE_WAIT
অর্থাত্ সংযোগটি বন্ধ করার প্রক্রিয়াধীন এবং পাশের নিজস্ব CLOSE
অপারেশন জারির জন্য অপেক্ষা করে। আমি মনে করি এটি যথেষ্ট ন্যায্য যা isConnected
ফিরে আসে true
এবং isClosed
ফিরে আসে false
তবে কেন এমন কিছু হয় না isClosing
?
নীচে পরীক্ষার ক্লাস রয়েছে যা প্রাক-এনআইও সকেট ব্যবহার করে। তবে অভিন্ন ফলাফল এনআইও ব্যবহার করে প্রাপ্ত হয়।
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
...