0

I am making a multithreaded server-client app where every client has its own dedicated thread. Server and client communicate using a specific message format that ends with "END\r\n". For this purpose, I thought of using Scanner class and its useDellimiter method. Here is the code

     private static String getMessage(InputStream input) throws IOException {
           Scanner n = new Scanner(input); 
           n.useDelimiter("END\r\n");
           while(!n.hasNext()) {} 
           return n.next(); 

     }

The problem I ran into is that n.next() doesn't block if the message isn't available instead it throws an exception. I fixed this with basic polling with this while loop, it works, but that seems like bad practice. Can I make n.next() block? Is there a better way of achieving what I want without using the Scanner class?

Danilo Gacevic
  • 474
  • 3
  • 13
  • Maybe the thread [hasNext() - when does it block and why?](https://stackoverflow.com/a/16874004/10386912) helps –  Nov 26 '18 at 16:14
  • 1
    `hasNext()` and `next()` always blocks unless the stream has been closed in which case there is no more data. – Peter Lawrey Nov 26 '18 at 17:11

1 Answers1

2

Here is a self contained program which shows that hasNext() blocks as expected when there is no input. It blocks until the stream is closed at which point there is no more data.

    ServerSocket ss = new ServerSocket(0);
    Socket s = new Socket("localhost", ss.getLocalPort());
    Socket s2 = ss.accept();
    Scanner scanner = new Scanner(s.getInputStream());
    scanner.hasNext();

blocks, and a thread dump shows

"main" #1 prio=5 os_prio=0 cpu=578.13ms elapsed=12.74s tid=0x000001eda6aee000 nid=0x6220 runnable  [0x0000004848afe000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(java.base@11.0.1/Native Method)
    at java.net.SocketInputStream.socketRead(java.base@11.0.1/SocketInputStream.java:115)
    at java.net.SocketInputStream.read(java.base@11.0.1/SocketInputStream.java:168)
    at java.net.SocketInputStream.read(java.base@11.0.1/SocketInputStream.java:140)
    at sun.nio.cs.StreamDecoder.readBytes(java.base@11.0.1/StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(java.base@11.0.1/StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(java.base@11.0.1/StreamDecoder.java:178)
    - locked <0x00000007ffc9b270> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(java.base@11.0.1/InputStreamReader.java:185)
    at java.io.Reader.read(java.base@11.0.1/Reader.java:189)
    at java.util.Scanner.readInput(java.base@11.0.1/Scanner.java:882)
    at java.util.Scanner.hasNext(java.base@11.0.1/Scanner.java:1446)
    at A.main(A.java:33)
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130