Skip to main content

Socket Performance on Windows

3 replies [Last post]
jeffreylyon
Offline
Joined: 2010-01-28

For some odd reason, the following call to InputStream.read reads data several orders of magnitude faster on Linux and OS X than on Windows XP/Vista/NT using the most recent Java 6 SE JVM for each platform:

final InputStream inputStream = pSocket.getInputStream();
int offset = 0;
final byte[] data = new byte[packetSize];
System.err.println(new Date().getTime() + " Array allocated");
while (offset < packetSize)
{
try
{
System.err.println(new Date().getTime() + " Ready to start reading.");
final int read = inputStream.read(data, offset, (packetSize - offset));
System.err.println(new Date().getTime() + " Read " + read);
if (read == -1)
{
return null;
}
offset += read;
}
catch (SocketTimeoutException e)
{
return null;
}
}

The ServerSocket creating the above Socket is setup as such:

serverSocket = new ServerSocket();
serverSocket.setPerformancePreferences(3, 2, 1);
serverSocket.setSoTimeout(1000);
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(pPort), 10);

... and I've tried playing with setPerformancePreferences to no avail.

I've tried everything I can think of to figure this one out. Does anyone out there have any insight?

Thanks in advance,

Jeffrey

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tarbo
Offline
Joined: 2006-12-18

A wild, wild stab in the dark, here.

I read some time (years) ago that Windows needs to copy bytes from one buffer to another when it writes to a stream. Linux and OS X have a zero-copy mode where they simply 'switch' buffers in between reading and writing. I heard the Java team was working on leveraging this option whenever possible.

Maybe they made some serious progress. :)

Do you have specific numbers and configurations (hardware & software) for us?

Cheers,
Jonathan

jeffreylyon
Offline
Joined: 2010-01-28

I suspect that the problem had to do with the different ways Windows and *NIX handle TCP handshaking; the original code wrote 4 bytes to indicate the number of bytes forthcoming and, then, wrote that number of bytes to a TCP socket. By making one call to write() with a byte[] which contained the 4-byte size prefix as well as the data itself, performance improved by 4000% over the wire on a Windows box.

Thanks, Jonathan, for the wild stab.

J

sowmyacrao
Offline
Joined: 2010-04-20

In java Socket Programming we have a method Socket.keepAlive(true) method to check the end to end conenction.
Does this method opens a new port for evert packet which it send?
In my program i was checking with the tool netstat -an which was showing like as follows:

tcp 0 3328 16.181.58.27.7278 2.141.3.37.3821 ESTABLISHED
tcp 0 3328 16.181.58.27.7278 2.141.3.37.3789 ESTABLISHED
tcp 0 3328 16.181.58.27.7278 2.141.3.37.3806 ESTABLISHED
tcp 0 3328 16.181.58.27.7278 2.141.3.37.3844 ESTABLISHED

Please let me knw what is the root cause of this kind of probelm and any resolution?