मुझे Scanner
कक्षा के साथ एक बहुत ही अजीब समस्या का सामना करना पड़ रहा है। मैं एक विशेष ईओएफ टोकन के साथ Socket
से संदेशों को पढ़ने के लिए Scanner
का उपयोग कर रहा हूं। सबकुछ ठीक काम करता है अगर क्लाइंट एक बार में सभी अनुरोध लिखता है, या अनुरोधों के पास डेटा है, लेकिन अवरुद्ध hasNext()
ऑपरेशन सर्वर पर लटकता है, और बदले में क्लाइंट, जब संदेशों में संदेश लिखा जाता है और अगला टोकन खाली स्ट्रिंग होना चाहिए ।java.util.Scanner हैनक्स्ट पर लटकता है()
इसका कारण क्या होगा? मैं इससे बचने के बारे में कैसे जा सकता हूं?
यहां मैं जो करने का प्रयास कर रहा हूं उसका एक सरलीकृत संस्करण है, \n
परीक्षण उद्देश्यों के लिए उपयोग किया जा रहा है, मान लें कि डिलीमीटर कोई स्ट्रिंग हो सकता है।
सर्वर कोड:
ServerSocketChannel serverChannel = null;
try {
serverChannel = ServerSocketChannel.open();
ServerSocket serverSocket = serverChannel.socket();
serverSocket.bind(new InetSocketAddress(9081));
SocketChannel channel = serverChannel.accept();
Socket socket = channel.socket();
InputStream is = socket.getInputStream();
Reader reader = new InputStreamReader(is);
Scanner scanner = new Scanner(reader);
scanner.useDelimiter("\n");
OutputStream os = socket.getOutputStream();
Writer writer = new OutputStreamWriter(os);
while (scanner.hasNext()) {
String msg = scanner.next();
writer.write(msg);
writer.write('\n');
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverChannel != null) {
try {
serverChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
कार्य ग्राहक:
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress("localhost", 9081));
InputStream is = socket.getInputStream();
Reader reader = new InputStreamReader(is);
Scanner scanner = new Scanner(reader);
scanner.useDelimiter("\n");
OutputStream os = socket.getOutputStream();
Writer writer = new OutputStreamWriter(os);
writer.write("foo\n\nbar\n");
writer.flush();
System.out.println(scanner.next());
System.out.println(scanner.next());
System.out.println(scanner.next());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
फांसी ग्राहक:
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress("localhost", 9081));
InputStream is = socket.getInputStream();
Reader reader = new InputStreamReader(is);
Scanner scanner = new Scanner(reader);
scanner.useDelimiter("\n");
OutputStream os = socket.getOutputStream();
Writer writer = new OutputStreamWriter(os);
writer.write("foo\n");
writer.flush();
System.out.println(scanner.next());
writer.write("\n");
writer.flush();
System.out.println(scanner.next());
writer.write("bar\n");
writer.flush();
System.out.println(scanner.next());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
मैं सॉकेट चैनल को बंद करने के बाद कर रहा हूँ सभी इनपुट पढ़ा जा चुका है, इस परोक्ष अंतर्निहित सॉकेट (रों) बंद कर देता है , चाहे सॉकेट को बंद होने की आवश्यकता होने से पहले प्रोग्राम लम्बे समय तक लटका हुआ हो। टोकन को एक संदेश डिलीमीटर के रूप में उपयोग किया जाता है, इसलिए एक सत्र के दौरान कई संदेश भेजे जा सकते हैं, यह स्ट्रीम के अंत का पता लगाने के बारे में नहीं है।मुझे पता है कि धारा के अंत में हैनेक्स्ट() फ़ंक्शन वापस आने का कारण होगा। –
कृपया याद रखें कि यह समस्या को पुन: उत्पन्न करने के लिए सिर्फ एक उदाहरण है, उत्पादन कोड वास्तव में गैर-अवरुद्ध सॉकेट चैनल का उपयोग करता है, लगातार कनेक्शन स्वीकार करता है, और सॉकेट के पढ़ने, लिखने और बंद करने के लिए कार्यकर्ता धागे को स्पॉन्स करता है। –