Reputation: 119
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"?
Upvotes: 0
Views: 3559
Reputation: 119
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()));
Upvotes: 0
Reputation: 533520
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.
Upvotes: 6