InputStream never gets EOF

Before anything, allow me to show you my client code:

                    String command;
                    socket.setSoTimeout(5000);
                    while(true) {
                        try {
                            final byte[] targetArray = new byte[is.available()];
                            final int x = is.read(targetArray);
                            if (x == -1) {
                                System.out.println("end");
                                break;
                            }
                            if (x == 0) continue;
                            command = new String(targetArray);
                            handleCommand(command).start();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }

once connected to the actual socket, the client sends out some authentication data, but doesn’t recieve any data, now, it waits to recieve data from the server, and when it does, it processes it fine etc, except, when I stop the server (literally shutting down the program), nothing happens, when in reality, im expecting it to send EOF (-1). Instead it just spams out 0 consistently.

Answer

According to available method’s documentation (emphasis mine):

Returns an estimate of the number of bytes that can be read …

and

It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream …

So according to the minimal code you posted, you shouldn’t use available to allocate the buffer, because it may always return 0 which in turn makes the read operation always return 0. But according to your question you only see this behaviour when the sending program is closed which should mean that:

  1. The available method correctly returns the buffered number of bytes in the stream, so this is why you receive the data. Even if you consume received data faster than the sending end sends (so some zeros may show up in available) you just continue and never handle that case, which makes some other loop in the future to capture the (eventually) received non-zero length data.
  2. Once the sending end is closed, there will be a point after which it will always return 0 since it has no data. So you allocate zero length buffer, and the read method first checks that your buffer is zero length, rather than EOF.

So make sure the allocated buffer is of size at least 1.

Also, according to the Socket#getInputStream method’s documentation:

If there are no bytes buffered on the socket, and the socket has not been closed using close, then available will return 0.