Чтение данных из inputtream без клиентской стороны "flush ()" - PullRequest
0 голосов
/ 31 января 2012

Я реализовал программу на Java, которая считывает данные с GPS-устройств через 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()));

Тем не менее, мы обнаружили, что произошла большая задержка (то есть большое отклонение между Sys из «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();

Однако, если я добавлю «Thread.Sleep (10 * 1000)» перед «out.flush ()» и «out.close ()», задержка на стороне сервера станет 10 секунд ... Поэтому я подозреваю, если устройство GPS не выполнило "сброс" и, как следствие, задержка в inputtream.read () на стороне сервера ...

К сожалению, у нас нет контроля над вызовами TCP устройства GPS, поэтому я не могу внести в него какие-либо изменения, чтобы заставить его «сбрасывать» сообщение в мой входной поток ... Пожалуйста, посоветуйте, если есть какие-либо средства, которые серверная сторона может читать данные из inputtream без такой задержки, даже если клиентская сторона (то есть устройство GPS) не выполняет "сброс"?

Ответы [ 2 ]

6 голосов
/ 31 января 2012

Получатель не может прочитать данные, которые не были отправлены.Он не может заставить другой конец отправлять данные, которые также не были отправлены.

0 голосов
/ 01 февраля 2012

Спасибо за совет Питера Лори, и мы использовали TCPDump, чтобы доказать, что данные передаются на наш сервер через несколько секунд после установления соединения.Вот почему серверная программа зафиксировала большую задержку.

Но затем мы выполняем некоторый нагрузочный тест с той же серверной программой, имея 4000 тестов GPS-устройств, отправляющих данные на нее каждые 5 минут, каждая из них составляет около 300 байт.

Мы попытались изменить код сервера, введя Threadpool для обработки извлечения данных TCP и надеясь, что это даст нам лучшую производительность.

Мы включили TCPDump и обнаружили, что на этот раз отклонение времени былонаходится между отметкой времени TCPDump и отметкой времени «START ...», записанной в программе Java.Отклонение составляло от нескольких секунд до менее 20 секунд ...

Есть какие-либо предложения по устранению проблемы?

Инициализация пула потоков:

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);

Внутри RetrieveTcpMessage.run (), аналогично предыдущему:

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()));
...