BufferedReader в программировании сокетов - PullRequest
0 голосов
/ 13 июля 2020

Когда я пытаюсь отправить ввод от клиента, если я не конкатенирую «\ r \ n» в конце строки, мой поток ввода будет ждать вечно. Я видел разные похожие сообщения, но не мог найти подходящего решения. Мой код выглядит следующим образом:

public void run() {
    
    PrintWriter out = null;
    BufferedReader in = null;
    try {
        out = new PrintWriter(clientSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        String line;

        if (in.ready()) {
            if ((line = in.readLine()) != null) {
                System.out.println("Received from client: " + line);
                out.write("Echoing: " + line);
                out.flush();
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        out.close();
        try {
            in.close();
            clientSocket.close();
            System.out.println("Closing connection from " + socketAddress + ", #" + connectionId);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1 Ответ

0 голосов
/ 14 июля 2020

Если вы хотите прочитать только часть отправленных данных, используйте метод read(char[]) вместо метода readLine. Этот метод возвращает количество прочитанных символов как int. Пример:

     char[] buffer = new char[2000];
     int read;
     if ((read = in.read(buffer)) != -1) {
            String line = new String(buffer, 0, read);
            System.out.println("Received from client: " + line);
            out.write("Echoing: " + line);
            out.flush();
      }

Далее вы увидите, что этот код иногда не может прочитать все сообщение, которое вы отправляете из PHP, или что два или более сообщения читаются как одно.

Если вы хотите исправить это:

Это никогда не сработает, и это не из-за PHP или Java. Вы используете TCP, потоковый протокол. Нет гарантии, что сообщение, которое вы пишете в сокет из программы PHP, будет доставлено получателю целиком. Сообщение может быть разбито, и вам потребуется несколько вызовов функций сокета для его чтения. Или это может go другое направление, и один вызов read возвращает более одного сообщения.

Решение состоит в том, чтобы добавить некоторую рамку для сообщений, чтобы получатель знал, когда он полное сообщение. Сообщение всегда заканчивается разрывом строки, если сами сообщения представляют собой отдельные строки. Другое решение - отказаться от TCP и использовать вместо него протокол, ориентированный на сообщения (например, UDP), но это повлечет за собой свои собственные сложности.

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