Best practice for reading / writing to a java server socket
There are basically three ways to do network I/O:
Blocking. In this mode reads and writes will block until they can be fulfilled, so if you want to do both simultaneously you need separate threads for each.
Non-blocking. In this mode reads and writes will return zero (Java) or in some languages (C) a status indication (return == -1, errno=EAGAIN/EWOULDBLOCK) when they cannot be fulfilled, so you don't need separate threads, but you do need a third API that tells you when the operations can be fulfilled. This is the purpose of the
select()
API.Asynchronous I/O, in which you schedule the transfer and are given back some kind of a handle via which you can interrogate the status of the transfer, or, in more advanced APIs, a callback.
You should certainly never use the while (in.available() > 0)
/sleep()
style you are using here. InputStream.available()
has few correct uses and this isn't one of them, and the sleep is literally a waste of time. The data can arrive within the sleep time, and a normal read()
would wake up immediately.
Schifty
Updated on June 20, 2022Comments
-
Schifty almost 2 years
How do you design a read and write loop which operates on a single socket (which supports parallel read and write operations)? Do I have to use multiple threads? Is my (java) solution any good? What about that sleep command? How do you use that within such a loop?
I'm trying to use 2 Threads:
Read
public void run() { InputStream clientInput; ByteArrayOutputStream byteBuffer; BufferedInputStream bufferedInputStream; byte[] data; String dataString; int lastByte; try { clientInput = clientSocket.getInputStream(); byteBuffer = new ByteArrayOutputStream(); bufferedInputStream = new BufferedInputStream(clientInput); while(isRunning) { while ((lastByte = bufferedInputStream.read()) > 0) { byteBuffer.write(lastByte); } data = byteBuffer.toByteArray(); dataString = new String(data); byteBuffer.reset(); } } catch (IOException e) { e.printStackTrace(); } }
Write
public void run() { OutputStream clientOutput; byte[] data; String dataString; try { clientOutput = clientSocket.getOutputStream(); while(isOpen) { if(!commandQueue.isEmpty()) { dataString = commandQueue.poll(); data = dataString.getBytes(); clientOutput.write(data); } Thread.sleep(1000); } clientOutput.close(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }
Read fails to deliver a proper result, since there is no -1 sent. How do I solve this issue?
Is this sleep / write loop a good solution?