2013-03-10 1 views
-5

TCP 소스에서 데이터를 읽는 Java 프로그램은 데이터 소스의 클라이언트 역할을하는 내 프로그램이 더 빠를 때를 제외하고 모두 정상적으로 작동합니다 소스는 BufferedReader.ready()가 응답해야하므로 TCP 연결을 닫는 예외를 throw합니다. BufferedReader가 새로운 입력을 기다리는 것을 유지할 수있는 선호하는 방법/방법이 있습니까? 소스가 가끔씩 지연 될 수 있습니다.버퍼 된 소켓 판독기가 원격 연결에서 데이터를 기다리지 않습니다.

public aDataServer(String host, int port, StreamConnection aConnection) throws UnknownHostException, IOException { 
      this.aConnection = aConnection; 
      ndataServerSocket = new Socket(Inet4Address.getByName(host),port); 
      ndataServerReader = new BufferedReader(new InputStreamReader(ndataServerSocket.getInputStream())); 
     } 


public void run() { 
      try { 
       RemoteDevice dev = RemoteDevice.getRemoteDevice(aConnection); 
       OutputStream outputStream = aConnection.openOutputStream(); 
       OutputStreamWriter osw = new OutputStreamWriter(outputStream); 
       do { 
        try { 
         String ndata = ndataServerReader.readLine(); 


          osw.write(ndata+"\n"); 
          osw.flush(); 
          LOG.log(Level.INFO,"Sent"); 


        } catch(IOException io) { 
         LOG.log(Level.SEVERE, "Client device({0}) disconnected: \n{1}", new Object[]{dev.getFriendlyName(true), io.getMessage()}); 
         break; 
        } 
       }while(ndataServerReader.ready()); 
      } catch (IOException ioe) { 
       LOG.severe(ioe.getMessage()); 
      } finally { 
       try { 
        if (ndataServerSocket != null) { 
           ndataServerSocket.close(); 
        } 
        if (ndataServerReader 
          != null) { 
           ndataServerReader.close(); 
        } 
       } catch (IOException ex) { 
        LOG.log(Level.SEVERE, ex.getMessage()); 
       } 
      } 
+1

예외가 발생합니다. BufferedReader를 작성하고 읽는 방법에 대한 코드 스 니펫을 포함 할 수 있습니까? – dimo414

+0

일부 코드로 내 질문이 업데이트되었습니다. – user1945235

+0

예외 출력도 게시 할 수 있습니까? – dimo414

답변

0

당신은 ndataServerReader.ready()를 사용해서는 안 : 여기

내가 얘기하고있는 부분입니다. do/while 루프 (while 루프 일 것임)는 ndataServerReader.ready()이 더 많은 데이터를 읽을 수 있다고 가정하는 것으로 보입니다. 이는 더 이상 읽을 데이터가 아닙니다.

Javadoc for Readerready()으로 설명있어서

이 스트림이 판독 될 준비가되었는지 어떤지.

반환 값 : 다음 read()가 입력을 위해 차단되지 않으면 true, 그렇지 않으면 false 입니다. false를 반환해도 다음 읽기가 차단된다는 보장은 없습니다.

Reader.ready()은 판독기가 읽으려고하면 반환하기 전에 더 많은 데이터를 기다리는 경우 false를 반환합니다. 이것은 이 아니며은 판독기가 완료되었음을 의미하며 실제로는 이 메서드는 네트워크 스트림을 사용하여 작업 할 때 false를 반환하는 것으로 예상합니다. 지연 가능성이 있기 때문입니다.

귀하의 코드는 현재 한 줄 (do 블록)을 읽었을 가능성이 높습니다. 그러면 리더가 준비되어 있는지 (예 : while) 확인하고 성공적으로 완료되지 않은 것입니다. 예외가 발생하지 않습니다. SEVERE 수준의 로깅 메시지가 표시됩니다. 은 if

어떤 라인의 끝 문자는 포함하지 않는다 라인의 내용을 포함하는 문자열, 또는 null :

대신 ready()를 사용, 그것은 반환 말한다 readLine()의 문서화 된 행동을 활용 스트림의 끝은 되어 간단하고, 즉

에 도달했습니다 :

String ndata = reader.readLine(); 
while (ndata != null) { 
    osw.write(ndata+"\n"); 
    osw.flush(); 
    LOG.log(Level.INFO,"Sent"); 

    ndata reader.readLine(); 
} 

전체 입력 스트림을 읽는 데 충분합니다.

참고 자료 : What's the difference between (reader.ready()) and using a for loop to read through a file?

+0

덕분에 지금은 훨씬 더 의미가 있습니다. 이걸 제대로 이해한다면 기다리는 동안 엄청난 CPU 사용량을 초래하지 않을 것입니다. – user1945235

+0

스레드는 소스에서 충분한 데이터를 다시 얻을 때까지 스레드가 실제로 기다려야합니다 (실제 구현은 네이티브 OS 코드 임에도 불구하고 루프에서 실제로'Thread.sleep()를 기다립니다) 또는 허용 된 시간 초과보다 오래 걸립니다 이것은 Socket 객체에서 설정할 수 있습니다.이 경우 충분한 데이터가 반환되지 않았 음을 나타내는 예외가 발생합니다. – dimo414

관련 문제