2

I can't figure out why my Java Server with Socket and ServerSocket is that slow while sending objects. Here a small ping program to demonstrate my problem. If I run both client and server on the same machine, everything is fine ofc (<1ms ping time). However, if I move the Server to a Linux machine I get a ping time of >500ms (ping via command line to that machine says 20ms).

Thanks in advance


Server:

public static void main(String[] args) {
    try {
        ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0]));
        Socket socket = serverSocket.accept();

        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());

        oos.writeObject(System.currentTimeMillis());
        long time = (long)ois.readObject();

        System.out.println(System.currentTimeMillis()-time+" ms");

    } catch (Exception e) {
        System.out.println("Some error occured");
        System.exit(1);
    }
}

Client:

public static void main(String[] args) {
    try {
        Socket socket = new Socket(args[0], Integer.parseInt(args[1]));

        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

        long time = (long)ois.readObject();
        oos.writeObject(time);

    } catch (Exception e) {
        System.out.println("Some error occured");
        System.exit(1);
    }
}
Astraioz
  • 65
  • 2
  • 6
  • You seem to be comparing server time with client time. It is unlikely that the clocks are synchronized between the two machines to a millisecond. Try rewriting it to measure round trip time, using clock on the same machine: start the clock, send a ping to the server, read response, stop the clock. Also, `flush` the stream after you write to it. If this does not help, you may want to play around with [send and receive buffer sizes](http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#setSendBufferSize(int)), defaults may not be very suitables for messages this small. – Dima Jan 13 '15 at 14:44
  • @Dima adjusting the send and receive buffer sizes helped aswell, thanks. Now it is at 30ms same as the ping over command line. – Astraioz Jan 14 '15 at 08:27

2 Answers2

5

I looked around the web a bit and you are not the only person with this problem. This post also describes the same issue,

Basically, what you should do is instead of:

ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

You should write:

ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));

And periodically you would write:

oos.flush();//Write after you send data
GenuinePlaceholder
  • 685
  • 1
  • 10
  • 25
2

I had the same problem, simple connection had ping about 400ms. Try add this line after socket creating: socket.setTcpNoDelay(true);

Kright
  • 81
  • 4
  • Many thanks. This reduced a no-reason-whatsoever delay of about 40ms for both client and server running on the same host to less than 1ms. – user3745418 Jul 18 '17 at 15:00