0

I have implemented a Java program that reads data from GPS Devices through ServerSocket.

ServerSocket serverSocket = new ServerSocket(13811);
serverSocket.setReceiveBufferSize(receiveBufferSize);
Socket incomingSocket = serverSocket.accept();
InputStream stream = incomingSocket.getInputStream();
byte[] buffer = new byte[1000];
            StringBuffer sb = new StringBuffer();
System.out.println("START getting message from TCP stream: " + dateFormat.format(Calendar.getInstance().getTime()));

            while (stream.read(buffer) > 0)
            {
                sb.append(new String(buffer));
                System.out.println(sb.toString());
            }
System.out.println("[incomingMessage]: " + incomingMessage);

System.out.println("FINISHED getting message from TCP stream: " + dateFormat.format(Calendar.getInstance().getTime()));

However, we found out that there was large delay (i.e. large deviation between Sys out "START..." and "FINISHED..." time above). The time was spent on inputStream.read().

If I use a Java client to connect to the above server port and send data to it, the message is readable by server's inputStream within a few ms. Below shows the Java client code.

Socket socket = new Socket("localhost", 13811); 
DataOutputStream out = new DataOutputStream(new  BufferedOutputStream(socket.getOutputStream()));
String tobesend = "testing message 1";
out.writeBytes(tobesend);
out.flush();
out.close();

However, if I add a "Thread.Sleep(10*1000)" before "out.flush()" and "out.close()", the delay at Server side will become 10seconds... Therefore I suspect if the GPS Device did not perform the "flush" and resulting the delay of inputstream.read() at server side...

Unfortunately, we have no control on the GPS Device TCP calls so I can't make any modifications on it to enforce it to "flush" message to my inputstream... Please advice if there is any means that server side can read data from inputstream without such delay even the client side (i.e. the GPS device) do not perform a "flush"?

xlogger
  • 109
  • 1
  • 15
  • There's a question like that here: [http://stackoverflow.com/questions/1169739/java-tcp-socket-data-transfer-is-slow][1] [1]: http://stackoverflow.com/questions/1169739/java-tcp-socket-data-transfer-is-slow – eduyayo Jan 31 '12 at 17:52
  • Thanks for the ref. It seems like the link was talking about issue on the sender side ... I try to follow one of the reply there by wrapping the server's inputStream with BufferedInputStream, but still the same... Please enlighten if I get it wrongly – xlogger Jan 31 '12 at 18:31

2 Answers2

6

The receiver cannot read data which has not been sent. It cannot force the other end to send data which has not been sent either.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Sorry that I'm not familiar with socket programming... is that means the data are not actually sent to server side even writeBytes() has been done but "flush()" is not called? ... and nothing can be done on the receiver side? I'm just wondering if the GPS Device behave like what I have tested using the Java test client ... Do you have any suggestion on how I could review that? Thanks – xlogger Jan 31 '12 at 18:25
  • You can use wireshark to see the actual packet sent. If the GPS device has sent the data you will be able to see it. If it hasn't sent the data, there is nothing you can do except change the way the GPS Device works. – Peter Lawrey Jan 31 '12 at 19:39
0

Thanks for Peter Lawrey's advice and we used TCPDump to proved that the data are flushed to our server a few seconds after they establish the connection. That's why the server program captured the large delay.

But then, we perform some load test with the same Server program by having 4000 testing GPS devices pushing data to it every 5mins, each data is around 300bytes.

We tried to modify the server code by introducing Threadpool to handle the TCP data retrieval and hope that would give us better performance.

We have turned on TCPDump, and found that this time the time deviation was found between the TCPDump timestamp and the "START..." timestamp captured in the Java program. The deviation was around several seconds to less than 20 seconds...

Any suggestion on how to troubleshoot the issue?

Initialization of Threadpool:

blockingQueueForRetriveTCPMsg = new LinkedBlockingQueue<Runnable>(50);
threadPoolExecutorForRetriveTCPMsg = new ThreadPoolExecutor(
    50,1200, 0, TimeUnit.SECONDS,
    blockingQueueForRetriveTCPMsg, 
    new ThreadPoolExecutor.CallerRunsPolicy());

ServerSocket.accept() :

ServerSocket serverSocket = new ServerSocket(13811);
serverSocket.setReceiveBufferSize(receiveBufferSize);
Socket incomingSocket = serverSocket.accept();

RetrieveTcpMessage retrieveTcpMessage = new RetrieveTcpMessage(incomingSocket);
Thread retrieveTcpMessageThread = new Thread(retrieveTcpMessage);
threadPoolExecutorForRetriveTCPMsg.execute(retrieveTcpMessageThread);

Inside RetrieveTcpMessage.run(), simuilar to before:

InputStream stream = incomingSocket.getInputStream();
byte[] buffer = new byte[1000];
        StringBuffer sb = new StringBuffer();
System.out.println("START getting message from TCP stream: " +     dateFormat.format(Calendar.getInstance().getTime()));

        while (stream.read(buffer) > 0)
        {
            sb.append(new String(buffer));
            System.out.println(sb.toString());
        }
System.out.println("[incomingMessage]: " + incomingMessage);

System.out.println("FINISHED getting message from TCP stream: " +  dateFormat.format(Calendar.getInstance().getTime()));
xlogger
  • 109
  • 1
  • 15
  • 1
    Welcome to Stack Overflow! If you have a NEW question, please ask it by clicking the [Ask Question](http://stackoverflow.com/questions/ask) button. – oers Feb 02 '12 at 10:11