我正在使用 Java Process API 编写一个类,该类从网络接收二进制输入(例如通过 TCP 端口 A),对其进行处理并将二进制输出写入网络(例如通过 TCP 端口 B)。我使用的是Windows XP。代码如下所示。有两个函数,分别为 run()
和 receive()
:run 在开始时调用一次,而 receive 在通过网络接收到新输入时调用。 Run 和 receive 是从不同的线程调用的。
run进程启动一个exe并接收exe的输入输出流。 Run 还会启动一个新线程,将 exe 的输出写入端口 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());
}
}
receive 将接收到的输入从端口 A 转发到 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)
任何有关此问题的建议将不胜感激。
这意味着您在另一端已经关闭管道后才向管道写入内容。
这表明您的应用程序协议(protocol)中存在重大错误。
我是一名优秀的程序员,十分优秀!