Java 如何在此处正确关闭ssh连接/会话?
我有一个客户机/服务器套接字程序。 服务器部分通过ssh连接到主机,运行脚本,并将每一行输出发送到客户端 下面的服务器代码部分返回一个包含脚本输出的Java 如何在此处正确关闭ssh连接/会话?,java,ssh,client-server,Java,Ssh,Client Server,我有一个客户机/服务器套接字程序。 服务器部分通过ssh连接到主机,运行脚本,并将每一行输出发送到客户端 下面的服务器代码部分返回一个包含脚本输出的BufferedReader: public synchronized BufferedReader runScript(<params>) { BufferedReader br = null ; try { Connection conn = new Connection(host); conn
BufferedReader
:
public synchronized BufferedReader runScript(<params>) {
BufferedReader br = null ;
try {
Connection conn = new Connection(host);
conn.connect();
... // authentication part
Session sess = conn.openSession();
sess.execCommand("ascript");
InputStream stdout = new StreamGobbler(sess.getStdout());
br = new BufferedReader(new InputStreamReader(stdout));
} catch (Exception e) {
e.printStackTrace();
}
return br;
}
public synchronized BufferedReader runScript(){
BufferedReader br=null;
试一试{
连接连接=新连接(主机);
连接();
…//身份验证部分
会话sess=conn.openSession();
sess.execCommand(“ascript”);
InputStream stdout=new StreamGobbler(sess.getStdout());
br=新的BufferedReader(新的InputStreamReader(stdout));
}捕获(例外e){
e、 printStackTrace();
}
返回br;
}
上面的方法是从另一个服务器端类/代码调用的,如下所示,通过套接字将BufferedReader的每一行写入客户端,以便客户端在脚本运行时看到脚本的实时输出:
BufferedReader br = new UnixCommandExecutor().runScript(<params>);
String line;
while ((line = br.readLine()) != null) {
out.writeObject(line);
}
BufferedReader br=new UnixCommandExecutor().runScript();
弦线;
而((line=br.readLine())!=null){
out.writeObject(行);
}
runScript方法的明显问题是它不会关闭ssh连接和会话(ganymed ssh lib),因为它会在底层脚本仍然运行时立即返回BufferedReader(如果我没有弄错的话)。如果我在return语句之前关闭这些,则BufferedReader将不完整。
那么,在底层脚本完成后,如何在此处正确关闭连接/会话
(我知道try with resources并将使用它,但我怀疑它能否完全解决问题?我建议您重构代码,以便
- 将零件包装到对象中,然后处理关闭操作
- 或者,您可以立即使用读卡器,并在使用完毕后关闭连接
公共类ResultHandler{
字符串主机;
连接接头;
BufferedReader reader=null;
公共结果处理程序(字符串主机){
this.host=host;
}
public void connect()引发异常{
//如果您打算重用该对象,只需检查之前是否已正确清理
close();
conn=新连接(主机);
连接();
…//身份验证部分
//您可能希望将实际处理移到其他方法
会话sess=conn.openSession();
sess.execCommand(“ascript”);
InputStream stdout=new StreamGobbler(sess.getStdout());
br=新的BufferedReader(新的InputStreamReader(stdout));
}
公共BufferedReader getReader(){
返回此.reader;
}
公众假期结束(){
If(读卡器!=null){
reader.close();
}
如果(conn!=null){
康涅狄格州关闭();
}
}
公共图书馆{
close();
}
}
已同步的void runScript(){
ResultHandler处理器;
试一试{
handler=新的ResultHandler(主机);
connect();
//无论你需要做什么,都要消耗读者
}捕获(例外e){
e、 printStackTrace();
}最后{
//或者使用try with resource并为此实现适当的接口
if(处理程序!=null){
handler.close();
}
}
}
您需要告诉我们您正在使用的众多SSH api中的哪一个,但是其中肯定有一个close()
方法吗?@user207421我已经提到了api(ganymed),是的,其中当然有一个close()
方法。这不是问题的重点,这里的实际问题是,在命令完成之后,也就是在您消耗了它的所有输出之后,我应该把close()放在哪里。很明显,那显然是在哪里?除了runScript()
方法之外?非常感谢您的建议。我不想立即使用阅读器,因为这会在客户端显示脚本输出时消除“实时效果”。我认为,将不同的部分包装成一个自定义对象是一种可行的方法。