Чтение всех входных данных из сокета непрерывно - PullRequest
4 голосов
/ 09 декабря 2011

Я пишу простое клиент-серверное приложение Java для собственного использования.Это должно позволить клиентам отправлять однострочные текстовые сообщения и читать многострочные ответы.Этот вид связи должен повторяться много раз с использованием одного и того же соединения.

Это то, что у меня есть в клиенте для чтения ответов:

BufferedReader input = new BufferedReader(new InputStreamReader(server.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
    // processing here
}

Проблема в том, что readLine () блокируется, когда сервер отправляет первый ответ обратно, а клиент не может отправитьновые сообщения из-за этого.Это понятно.Наивный обходной путь может заставить сервер сигнализировать об окончании его вывода, посылая какое-то известное специальное строковое значение, которое клиент затем распознает и завершит цикл чтения.Однако есть ли лучшее решение этой проблемы?

Ответы [ 2 ]

4 голосов
/ 09 декабря 2011

Поскольку ваш клиент должен прочитать несколько многострочных ответов из одного соединения и обработать каждый блок ответа, это может быть полезно для вашего случая:

    BufferedReader input = new BufferedReader(new InputStreamReader(server.getInputStream()));
    String line;
    StringBuilder sb = new StringBuilder();
    while ((line = input.readLine()) != null) {
        if (line.equals("~~/START/~~"))
            sb = new StringBuilder();
        else if (line.equals("~~/END/~~")) {
            doSthWithParagraph(sb.toString());
            sb.delete(0, sb.length());
        } else
            sb.append(line);
    }

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

1 голос
/ 09 декабря 2011

Я бы не стал полагаться на readLine для вашего основного цикла, потому что readLine полагается на "будущие" данные (CR, или LF, или CR + LF, и возвращает ноль, если достигнут конец потока).Из-за этого, если за CR не следует LF, BufferedReader застревает.Этот readLine метод больше подходит для чтения содержимого файла.

В вашем случае я бы читал по одному символу за раз с

while ((myChar = input.read()) != -1) {
    // processing here, storing information in a buffer and taking appropriate actions if
    // A CR or LF is found
}

Но даже это поведение сомнительно, потому что Unicodechar может быть больше одного байта, поэтому поток может зависнуть, если отправляется первый байт, а не второй.Вы уверены, что ваше сообщение Unicode?Если нет, то InputStream будет более подходящим, чем Reader.

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