web-dev-qa-db-de.com

Zeitlimit für JSch-Sitzung

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?

7

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();
  }
}
2
Martin Prikryl