My program uses a SSL ServerSocket
to wait for incoming connections and receive data.
The client connects to the server and writes a sequence of 10-byte-chunks to the Socket
's OutputStream
. After each 10-byte-chunk the OutputStream
is flush()
ed because the chunk should arrive at the server as soon as possible (Note: WIFI is used here).
These chunks are then read by the server. Running the server on Ubuntu Linux using OpenJDK 7 works fine.
But running the server on Windows using Suns Java 7 causes the following problem:
I measured the time on the server between the received chunks. I noticed that although the client uses flush()
after a chunk was written, the data is sometimes received/read by the server too late.
For example:
It takes 265ms to receive the first chunk. The next 15 chunks have a delay of 0ms to 16ms.
After that the next chunk arrives after 172ms. But the following 10 chunks again need only 0ms to 16ms.
So it seems that first some bytes are received and buffered by the InputStream. Then at some point (e.g. more than 150ms later) the InputStream
's read
-method returns some data. After that the read
-method returns data immediately (0ms to 16ms) for some bytes. And then it needs some time again.
I know that an InputStream
uses buffers and the read
-method blocks until a new byte is available. But it seems that the read
-method does not return data as fast as it could.
The client was always an Android-App. But since the problem does not occurr with the server running on Linux (always 20ms avg. between chunks) the problem must be the server or JRE.
Any ideas on how to solve the problem? I really need a "fluid" transfer of chunks sent by the client, because interactions on the Android-App should be shown on the server as an animation in near realtime. But with a delay of 265ms these animations stuck.
InputStream buffers data
No it doesn't. There isn't any InputStream buffering, unless you use a BufferedInputStream. Your sends are being coalesced by the TCP Nagle algorithm, in the kernel. Call Socket.setTcpNoDelay(true) at the sender.
You should be aware that sending 10-byte chunks over SSL is extremely inefficient. SSL itself has a record overhead of about 44 bytes, and TCP another twenty, so you have a data explosion of nearly 4x. Use plaintext if you possibly can for this.