Java-сокет: два символа новой строки быстрее, чем один символ новой строки - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть простое клиент-серверное приложение.Сервер на Java, клиент на Python3.Сервер ждет одного клиента, а затем общается с ним вечно следующим образом.Сервер читает строку с клиента и отправляет сообщение «гггг» обратно.Таким образом, со стороны клиента разговор может выглядеть примерно так:

xxxx
> yyyy
xxxx
> yyyy
xxxx
> yyyy
...

У меня проблема со скоростью общения.Я измеряю время, которое требуется серверу, чтобы прочитать запрос клиента, и оно составляет около 40 мс.Однако самое удивительное то, что, если клиент добавляет дополнительную новую строку '\ n' к каждому из своих сообщений, продолжительность падает до ~ 0 мс.В чем может быть причина этого и как я могу это исправить, чтобы мне не приходилось включать искусственный перевод строки в запрос каждого клиента?

Для полноты я также предоставляю код на стороне сервера и на стороне клиента.

Сторона сервера:

import java.io.*;
import java.net.*;
import java.time.*;
import java.util.*;

class Server {
  public static void main (String[] args) {
    Clock clock = Clock.systemDefaultZone();
    try {
      ServerSocket server = new ServerSocket();
      server.bind(new InetSocketAddress("127.0.0.1", 4248));
      Socket client = server.accept();

      Scanner sc = new Scanner(client.getInputStream());
      PrintStream ps = new PrintStream(client.getOutputStream());

      while (true) {
        Instant start = clock.instant();
        String msg = sc.nextLine();
        Instant end = clock.instant();
        System.err.format("Took me %d ms to receive the message\n", Duration.between(start, end).getNano() / 1000000);
        ps.println("yyyy");
      }
    }
    catch (IOException exc) {}
  }
}

Сторона клиента:

import socket, sys

sock = socket.create_connection(("127.0.0.1", 4248))
fin = sock.makefile('r')
fout = sock.makefile('w')

while True:
  print("xxxx", file = fout, flush = True)
  msg = fin.readline().rstrip('\n');
  print(msg, file = sys.stderr)

Мы получаем «быстрый» клиент, заменив «xxxx» на «xxxx \ n».Обратите внимание, что Python3 автоматически печатает новую строку после каждого сообщения, поэтому первое действительно «xxxx \ n», а второе «xxxx \ n \ n».

1 Ответ

0 голосов
/ 20 ноября 2018

Я измеряю время, которое требуется серверу для чтения запроса клиента

Мало того, но вы также измеряете (хотя бы частично) время, пока клиент не отправит свой запрос.

Всего лишь догадка

Клиент Python является узким местом и не может идти в ногу с сервером Java.Сервер nextLine() всегда ждет, пока клиент напечатает что-либо.
Когда вы изменяете print("xxxx") на print("xxxx\n"), печатаются сразу две строки, что удваивает скорость вывода строки клиента.Теперь все наоборот: клиент отправляет сообщения быстрее, чем сервер может их обработать, и клиент readline() должен ждать сервера.
Обратите внимание, что в последнем случае сообщения чередуются между "xxxx" и "".Это, вероятно, не то, что вы хотите.Однако вы можете использовать print("xxxx\nxxxx").

. Вы можете проверить эту теорию, написав Java-клиент, который использует println("xxxx").Предполагая, что Java-клиент работает быстрее, чем Python-клиент, я ожидаю, что измеренное время будет меньше 40 мс, но, возможно, чуть больше 0 мс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...