2010-03-08 3 views
1

자바 프로세스 API를 사용하여 네트워크에서 바이너리 입력 (예 : TCP 포트 A)을 수신하고이를 처리하고 네트워크에 바이너리 출력을 씁니다. TCP 포트 B). Windows XP를 사용하고 있습니다. 코드는 다음과 같습니다. run() 및 이라는 두 가지 기능이 있습니다. 즉, 시작시 한 번만 실행되고 네트워크를 통해 수신 된 새 입력이있을 때마다 receive가 호출됩니다. 실행 및 수신은 다른 스레드에서 호출됩니다.Java 프로세스 "파이프가 종료되었습니다."문제가 발생했습니다.

실행 프로세스는 exe를 시작하고 exe의 입력 및 출력 스트림을 수신합니다. 또한 실행하면이 EXE에 전달하는 포트 (A)로부터 수신 된 입력을 수신 포트 B.

public void run() { 
     try { 
      Process prc = // some exe is `start`ed using ProcessBuilder 
        OutputStream procStdIn = new BufferedOutputStream(prc.getOutputStream()); 
      InputStream procStdOut = new BufferedInputStream(prc.getInputStream()); 
        Thread t = new Thread(new ProcStdOutputToPort(procStdOut)); 
        t.start(); 

        prc.waitFor(); 
        t.join(); 
        procStdIn.close(); 
        procStdOut.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      printError("Error : " + e.getMessage()); 
     } 
    } 

에 EXE의 출력을 기록 할 새로운 쓰레드를 시작한다.

public void receive(byte[] b) throws Exception { 
     procStdIn.write(b); 
    } 

    class ProcStdOutputToPort implements Runnable { 
     private BufferedInputStream bis; 
     public ProcStdOutputToPort(BufferedInputStream bis) { 
      this.bis = bis; 
     } 
     public void run() { 
      try { 
       int bytesRead; 
       int bufLen = 1024; 
       byte[] buffer = new byte[bufLen]; 
       while ((bytesRead = bis.read(buffer)) != -1) { 
        // write output to the network 
       } 
      } catch (IOException ex) { 
       Logger.getLogger().log(Level.SEVERE, null, ex); 
      } 
     } 
    } 

문제

내가 직후 receive() 내부에 다음과 같은 스택과 prc.waitfor() 수익을 얻고 있다는 점이다. 행 번호는 스택이 exe에 쓰는 동안 표시됩니다.

The pipe has been ended 
java.io.IOException: The pipe has been ended 
at java.io.FileOutputStream.writeBytes(Native Method) 
at java.io.FileOutputStream.write(FileOutputStream.java:260) 
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105) 
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) 
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:109) 
at java.io.FilterOutputStream.write(FilterOutputStream.java:80) 
at xxx.receive(xxx.java:86) 

는 이것에 대해 어떤 조언을 이해할 수있을 것이다.

답변

1

이것은 다른 쪽 끝이 이미 닫은 후에 파이프에 쓰고 있음을 의미합니다.

이는 응용 프로그램 프로토콜에 중대한 오류가 있음을 나타냅니다.

+0

닫힌 파이프는 exe 프로세스에 쓰는 데 사용되는 파이프입니다. 문제의 프로토콜은 Java Process API입니다. –

+0

Java Process API는 프로토콜을 가지고 있지 않습니다. '다른 쪽 끝은 이미 닫았습니다'라고 당신이 간청 한 과정입니다. 그래서 당신은 독서가 중단 된 후에 그 과정에 무언가를 쓰고 있습니다. 그래서 문제의 프로토콜은 당신의 어플리케이션과 당신이 실행하는 프로세스 사이의 프로토콜입니다. – EJP

+0

이것은 이상한 것입니다, 나는 명령 프롬프트를 사용하여 java 외부의 다른 프로세스를 테스트했고 거기에서 잘 작동합니다. Java 코드에 버그가있는 것 같습니다. 귀하의 의견에 감사드립니다. –

0

나는 최근에 같은 문제가 있었으며 해결책을 찾았습니다.

우선 "파이프가 종료되었습니다"오류는 Java 오류가 아닙니다. 이는 Windows 시스템에서 발생합니다. MSDN에 따르면 : 당신이 파이프에 를 작성하려는 경우

사용하여 프로세스가 파이프를 닫거나 있으며, 사용 가능한 독자가 없습니다.

매우 유익하지 않습니다. 그러나 프로세스가 파이프 자체를 닫은 경우 프로세스에서 오류가 발생했을 수 있습니다. 이를 확인하기 위해

, 오류 파일로, 예를 들어, 공정에서 나오는 재 :

.\libs\srcML-Win\src2srcml.exe: unrecognised option `--language Java' 
Try 'src2srcml --help' for more information. 
: (나는 SrcML 파서을 실행하기 위해 노력했습니다) 내 경우

File f = new File("errors.txt"); 
pb.redirectError(f); 

파일이 포함 된

이 문제를 해결하면 문제가 해결됩니다.

관련 문제