我正在使用SSH Ganymed库别名Trilead别名Orion。
我试图理解会话的确切行为,因为我需要将ssh连接打开很长时间(可能永远打开),并在jvm崩溃或类似的情况下关闭它。
所以我的问题是。假设我做了这样的事:
Connection conn = new Connection(this.hostName, this.port);
conn.addConnectionMonitor(new ConnectionMonitor()
{
@Override
public void connectionLost(Throwable reason)
{
System.out.println("Connection Lost " reason.getMessage());
}
});
conn.connect(null, 1000, 20000);
conn.authenticateWithPublicKey(this.user, keyfile, this.password);
Thread.sleep(30000); //sleep the Thread for 30 seconds
Session sess = conn.openSession();
sess.execCommand("ls");
conn.close();而且,在线程休眠的30秒内,我断开了我的网络接口来模拟网络问题。
1)断开连接事件不会被connectionMonitor截获,连接丢失消息也不会被打印出来。
Session sess = conn.openSession();执行时,进程将被阻塞,除非我不再连接网络接口,否则不会发生任何事情。这是因为,从Ganymed代码来看,由于未检测到断开连接事件,会话将被打开,并且在会话成功之前存在一个打开会话的锁。
因此,我的问题是:1)这种行为是想要的还是这是一个bug? 2)在Connection.openSession()方法和Connection.connect()方法中是否存在设置超时的方法?
提前谢谢。
发布于 2013-01-05 01:05:15
我认为问题是,您不能模拟ssh断开通过拔掉电缆30秒。看看这个:如果在终端上打开ssh连接--拔掉电缆-- ssh客户端也会阻塞,但在电缆再次插入后会自动重新连接。我想你的代码也会这么做。
如果客户端和服务器之间在配置的时间内没有发送数据,即一段时间的不活动时间,则通常会断开连接,而不管电缆是否已插入。默认情况下,此时间段很可能大于30秒。
在sshd服务器上可以配置
ClientAliveInterval TCPKeepAlive ClientAliveCountMax
这些参数将决定服务器等待多长时间才能从客户端获得一些数据,以及他将接受一个简单的保持生存的数据包而不是真正的数据的频率。在客户端上可以配置
ServerAliveInterval
如果ClientAliveInterval小于ServerAliveInterval (服务器期望保持存活的数据包比客户端发送的数据包更频繁),那么在ClientAliveInterval不活动量之后,您将被断开连接。这样你就可以测试你的代码。
这些配置也是保持ssh连接无限期打开的关键。如果您的ServerAliveInterval小于ClientAliveInterval -客户端将发送比服务器预期更频繁的保持活动数据包-则您的连接将无限期地打开。
在这里找,https://www.simplified.guide/ssh/disable-timeout
我认为重新启动服务器或客户端机器仍然会导致断开连接。如果客户端机器正在收缩,无论如何您需要再次运行整个代码,如果服务器机器重新启动,连接监视器就会启动并重新连接。
https://stackoverflow.com/questions/13496294
复制相似问题