views:

605

answers:

4

I am processing time critical messages which are routed to me via a very slow network connection. I am connecting to the originating server (which I have no control over) with a Java TCP/IP Socket. The data is of varying length but is usually around 5000bytes and so ends up getting broken into multiple packets of roughly 1400 bytes.

Is there any way in my Java client-side code that I can control the size of the packets that are used to send me the data? I would like to experiment with explicitly using smaller packets sizes, for example 500 byte packets, which would decrease the time it takes for me to receive the first byte of the message at the (possible) cost of increased header overhead.

+1  A: 

You could try flushing your SocketOutputStreams after smaller amounts of bytes. That should create smaller packets though—as it’s system dependent—it won’t be guaranteed.

Bombe
I do not have any control of the server side (unfortunately). So I can not flush the SocketOutputStream
+2  A: 

I don't think you can control this from the client if you can't control or change your server. I suspect the server is packing the data into a 1500 byte ethernet frame (see here for details) and trying to optimise its delivery of data to you.

This 1500 bytes is called the MTU. You could possibly play around with this at the OS layer, but I suspect that'll bring you nothing but grief.

Brian Agnew
A: 

One way we found to solve the latency on the initial read was to set either the PUSH or URG flags in the TCP/IP header in the client request. The standard Java socket library doesn't let you do this as far as I know, but there's a library at:

http://www.savarese.org/software/vserv-tcpip/

that apparently does.

Disclaimers: this was way back when (Java 1.1.8 I think), we only ever used it on Windows and I suspect it was something of a hack then too so it may no longer work. And I also haven't used the Savarese library so can't vouch for it.

tonys
A: 

If you want to reduce the time to receive the first piece of data, try setting Socket.setTcpNoDelay(true); setTcpNoDelay

Peter Lawrey
I have done this, but it does not help with this problem. Even though it has all the data available, I want the server to send packets of 500 bytes.
Why? setTcpNoDelay(true) sends the data as soon as you write it. It cannot send it any sooner. Setting a packet size will only *slow down* your connection.
Peter Lawrey