2017-11-09 9 views
1

私はTrileadとJschをHg用のSSHクライアントとして使用していましたが、現代のキーサポートを提供しているように思われるのでSSHJで試しています。スケッチコードは SSHJ:execがハングしたりデータが失われたりする

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方法コピー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%で正常に動作しますが、時には水銀は、サーバーが早いとの接続を閉じたことを不平を言います。 cmd.close()にいつ呼び出すことができるかをサーバーのプロセスが終了したのでどのように知るべきですか?

答えて

0

これはSSHJのバグです(ticket 143参照)。この問題を回避するには、代わりに直接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())); 
     } 
    } 
}; 

startThreadToCopyInputStream(cmdOutputStream);に渡す前に。

関連する問題