我已经实现了一个Java程序,它通过ServerSocket从GPS设备读取数据。
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()));
然而,我们发现存在大的延迟(即Sys out“START ...”和“FINISHED ...”时间之间的大偏差)。花在inputStream.read()上的时间。
如果我使用Java客户端连接到上述服务器端口并向其发送数据,则服务器的inputStream可在几毫秒内读取该消息。下面显示了Java客户端代码。
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();
但是,如果我在“out.flush()”和“out.close()”之前添加“Thread.Sleep(10 * 1000)”,服务器端的延迟将变为10秒...因此我怀疑如果GPS设备没有执行“刷新”并导致服务器端inputstream.read()的延迟......
不幸的是,我们无法控制GPS设备TCP呼叫,因此我无法对其进行任何修改以强制它将“刷新”消息发送到我的输入流...请提示是否有任何方法服务器端可以即使客户端(即GPS设备)没有执行“刷新”,从输入流读取数据也没有这样的延迟?
答案 0 :(得分:6)
接收方无法读取尚未发送的数据。它不能强制另一端发送尚未发送的数据。
答案 1 :(得分:0)
感谢Peter Lawrey的建议,我们使用TCPDump证明数据在建立连接后几秒钟就被刷新到我们的服务器。这就是服务器程序捕获大量延迟的原因。
然后,我们使用相同的服务器程序执行一些负载测试,通过4000个测试GPS设备每隔5分钟向其推送数据,每个数据大约为300字节。
我们尝试通过引入Threadpool来处理TCP数据检索来修改服务器代码,并希望这会给我们带来更好的性能。
我们打开了TCPDump,发现这次在TCPDump时间戳和Java程序中捕获的“START ...”时间戳之间发现了时间偏差。偏差大约是几秒到不到20秒......
有关如何解决问题的任何建议吗?
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()));