2016-06-06 1 views
2

readLine() отлично работает во многих случаях, но несколько раз, строка, которую я читал BufferedReader.readLine(), является неполной линией. This вопрос о подобной проблеме. Однако решения не являются удовлетворительными. Решение там говорит, что это возможно из-за характера EOF. Но в моем случае я вообще не посылаю ни одного символа EOF. Ниже приведены мои коды:Java Socket.readLine() не всегда читает целое сообщение, разделенное newLine

/*Sending Code*/ 
public void sendToLocalDaemon(String msg){/*msg have no New line or \r*/ 
     localMachineWriter.println(msg); 
} 
/*Receiving Code*/ 
public int receiveFromCoordinator(){ 
     String response = ""; 
     while(true){/*Each message separated from new line will have its independent meaning.*/ 
      try{ 
        coordinator.setSoTimeout(1); 
        try{ 
         response = coordinatorReader.readLine(); 
        } 
        catch(java.net.SocketTimeoutException e){ 
         response = null; 
        } 
        if(response == null){ 
         return coordinatorsMessage.size(); 
        } 
        coordinatorsMessage.add(response); 
      } 
      catch(IOException e){ 
       log(e.getMessage()); 
       //System.exit(0); 
      } 
    } 
} 
/*This is how I set reader and writer*/ 

public void setReaderWriter() throws IOException{ 
    this.coordinatorWriter = new PrintWriter(coordinator.getOutputStream(),true); 
    this.coordinatorReader = new BufferedReader(new InputStreamReader(coordinator.getInputStream())); 
} 

Пожалуйста, предложите мне как-нибудь, чтобы сделать эту работу правильно. Или предложите мне другой способ, с помощью которого я могу читать целые сообщения со 100% гарантией.

+0

Не могли бы вы добавить ввод, который заставляет строку, прочитанную 'BufferedReader.readLine()' быть неполной, на ваш вопрос? Например, весь ввод и вывод 'readLine()'. –

+0

Как указано в одном из ответов в связанном вами вопросе, я думаю, что процесс, который записывается в ваш сокет, не закончил писать в ваш сокет, когда вы его читаете. – Supahupe

+0

@JonnyHenly Я могу вставить вход, но я исследовал его происхождение с любой строкой. Мои сообщения состоят из (0-9 и: и # и _ и буквы «E» и буквы «A»). Эта проблема возникает только с длинными строками. – PHcoDer

ответ

1

Проблема заключается в вашем таймауте чтения. Если это произойдет, вы можете потерять данные. Если readLine() раз в середине линии, часть, прочитанная до сих пор, теряется. Если вы установите слишком короткий, вы потеряете много данных, и вы установите слишком короткий. Вы должны установить его намного выше или вообще не использовать.

+0

Я думаю, что сокет будет тайм-аут, если он не получит ничего установленного времени. Это то, что говорит doc: «Включить/отключить SO_TIMEOUT с указанным таймаутом в миллисекундах. Если этот параметр установлен на ненулевой тайм-аут, вызов read() в InputStream, связанный с этим Socket, будет блокироваться только на это количество времени. Если истечение тайм-аута истекает, возникает исключение java.net.SocketTimeoutException, хотя Socket все еще действителен. Опция должна быть активирована до того, как будет введена операция блокировки. Тайм-аут должен быть> 0. Тайм-аут нуля интерпретируется как бесконечный тайм-аут ». – PHcoDer

+0

Согласен, вот что говорит документация. Ваш вопрос? – EJP

+0

Я пытаюсь сказать, что если readLine читает (и не блокирует в идеале), чем при тайм-ауте, это не должно прерываться. Или это прерывается точно при тайм-ауте независимо от того, какое действие выполняется на сокете? – PHcoDer