SSHJ:exec挂起或丢失数据

时间:2017-11-09 14:22:45

标签: sshj

我使用Trilead和Jsch作为Hg的SSH客户端,现在我正在尝试使用SSHJ,因为它似乎提供了更现代的关键支持。草绘的代码读作

SSHClient client = createClientAndAuthenticate();
Session session = client.startSession();
Command cmd = session.exec(command); // command usually is "hg -R /path/to/hg/repository serve --stdio"

startThreadToCopyInputStream(cmd.getOutputStream());

startThreadToCopyOutputStream(cmd.getInputStream());
startThreadToCopyOutputStream(cmd.getErrorStream());

cmd.join(); // here it hangs endlessly

startThreadToCopyInputStream方法将本地Hg进程中的所有字节复制到cmd.getOutputStream(),然后完成输入流。但与Trilead和JSch相比,cmd.getInputStream()cmd.getErrorStream()仍然无休止地开放。

我现在将代码更改为:

SSHClient client = createClientAndAuthenticate();
Session session = client.startSession();
Command cmd = session.exec(command); // command usually is "hg -R /path/to/hg/repository serve --stdio"

startThreadToCopyInputStream(cmd.getOutputStream());

startThreadToCopyOutputStream(cmd.getInputStream());
startThreadToCopyOutputStream(cmd.getErrorStream());

waitUntilInputStreamIsClosed();
cmd.close();

这种方法在90%的情况下运行良好,但有时Hg抱怨服务器提前关闭了连接。我应该怎么知道何时能够调用cmd.close(),因为服务器进程已经完成了?

1 个答案:

答案 0 :(得分:0)

看起来这是SSHJ中的一个错误(请参阅ticket 143)。解决方法是不直接使用VirtualPathUtility.ToAbsolute($"~/App_Themes/Default/Icons/myimage.gif") ,而是:

cmd.getOutputStream()

在传递给OutputStream cmdOutputStream = new FilterOutputStream(cmd.getOutputStream()) { @Override public void close() throws IOException { try { super.close(); } finally { client.getTransport().write(new SSHPacket(Message.CHANNEL_EOF).putUInt32(session.getRecipient())); } } }; 之前。