Ich verwende JSch 0.1.50, um eine Verbindung zum Remote-Server für mein CI-Jenkins-Plugin herzustellen. Nehmen wir an, ich versuche hier session.connect(60000);
für das Timeout von 60 Sekunden zu verwenden:
Session session = null;
try {
JSch jsch = new JSch();
if (rsaIdentity != null && !rsaIdentity.equals("")) {
jsch.addIdentity(rsaIdentity.trim());
}
session = jsch.getSession(serverLogin, serverHost, Integer.parseInt(serverPort));
session.setPassword(getDescriptor().getOpenPassword(encryptedPasswordString));
session.setConfig("StrictHostKeyChecking", "no"); // not use RSA key
int timeOut = Integer.parseInt(getDescriptor().getConnectionTimeOut());
session.connect(60000);
} catch (SocketTimeoutException e) {
logger.error(e.getMessage());
return false;
} catch (JSchException e) {
logger.error(e.getMessage());
return false;
}
Aber während der Ausführung dieses Codes während der Verbindung zu einem ziemlich langsamen Server steht das Zeitlimit Exception
jedes Mal in etwa 20 Sekunden an:
2016-01-25 13:15:55.982 [INFO] Connecting to server: devsrv26:22 as [user] ...
2016-01-25 13:16:16.991 [ERROR] Java.net.ConnectException: Connection timed out: connect
2016-01-25 13:16:16.992 com.jcraft.jsch.JSchException: Java.net.ConnectException: Connection timed out: connect
2016-01-25 13:16:16.992 at com.jcraft.jsch.Util.createSocket(Util.Java:389)
2016-01-25 13:16:16.993 at com.jcraft.jsch.Session.connect(Session.Java:215)
2016-01-25 13:16:16.993 at com.mycomp.jenkins.MyPlugin.perform(MyPlugin.Java:225)
76991-55982 = 21008 ms
Weiß jemand, was der Grund für dieses Timeout von 20 Sekunden ist?
Wenn Sie prüfen, wie Util.createSocket
implementiert ist, werden Sie feststellen, dass die timeout
nur eine obere Grenze der Verbindung definiert, keine untere Grenze, da die timeout
seltsamerweise nicht an eine zugrunde liegende Socket
übergeben wird.
Diese 20 Sekunden sind wahrscheinlich ein Standardlimit auf Betriebssystemebene.
Um es zu überschreiben, versuchen Sie, die SocketFactory
zu implementieren und sie mit Session.setSocketFactory
an die Sitzung anzuhängen.
Im Werk verwenden Sie die Socket.connect(SocketAddress endpoint, int timeout)
.
So etwas wie:
public class SocketFactoryWithTimeout implements SocketFactory {
public Socket createSocket(String Host, int port) throws IOException,
UnknownHostException
{
socket=new Socket();
int timeout = 60000;
socket.connect(new InetSocketAddress(Host, port), timeout);
return socket;
}
public InputStream getInputStream(Socket socket) throws IOException
{
return socket.getInputStream();
}
public OutputStream getOutputStream(Socket socket) throws IOException
{
return socket.getOutputStream();
}
}