Saying my requirement is: Either user type something in console (from system.in) or socket receive something, proceed to next step.
So I have a scanner
Scanner sc = new Scanner(System.in);
Have an Udp client. (a different input source)
DatagramSocket clientSocket = new DatagramSocket();
My code is
while (true) {
if (sc.hasNext()) {
String str = sc.next();
proceed(str)
} else {
clientSocket.receive(pack);
proceed(pack)
}
}
Obviously this code will not work. Because when checking sc.hasNext(), java is waiting user to type some input in console. Currently what I can do is open an thread for Udp client. If I change the order,
while (true) {
clientSocket.receive(pack);
if (not receive) read from system.in
}
It doesn't make sense, since receive() will keep waiting util receive something, it will never read from system.in concurrently.
So how can i achieve my requirement without using a thread?
Inspired by @Andriy Kryvtsun's answer, i did a quick test As he said, this is somehow using non-blocking read, and keep letting socket timeout, to emulate
InputStream ins = System.in;
byte buffer[] = new byte[512];
BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
DatagramSocket clientSocket = new DatagramSocket();
System.out.println("From buffer:" + clientSocket.getLocalPort());
while (true) {
try {
if (ins.available() > 0) {
String line = reader.readLine();
System.out.println("Read:" + line);
} else {
DatagramPacket pack = new DatagramPacket(buffer,buffer.length);
clientSocket.setSoTimeout(2000);
clientSocket.receive(pack);
System.out.println("Receive: " + new String(pack.getData()));
}
} catch (IOException e1) {
}
}
Use unblocking method call InputStream#available()
to get info if something ready for reading before using blocking Scanner#hasNext()
call.
Also you can call DatagramSocket#setSoTimeout(int timeout)
before call blocking receive(DatagramPacket p)
method. Thus you can break infinity waiting inside receive
method after timeout
period emulating unblocking reading.