2013-04-21 4 views
10

मैं एसएसएच का उपयोग कर स्थिर मार्ग प्रबंधन के लिए जावा जीयूआई प्रोग्राम लिख रहा हूं। मेरे कोड इस प्रकार है:जेएसएच: सत्र को जीवंत और ऊपर रखने के लिए

import com.jcraft.jsch.*; 
import java.io.*; 

public class Konsep { 
    String status; 
    static String username; 
    static String hostname; 
    String inputcommand; 
    String output; 
    static Session session; 

    JSch jsch = new JSch(); 

    public String status(String stringstatus) { 
     stringstatus = status; 
     return stringstatus; 
    } 

    public String InputCommand(String inputcommandstatus) { 
     inputcommandstatus = inputcommand; 
     return inputcommandstatus; 
    } 

    public void connect(String usernamelokal, String hostnamelokal, 
      String password, int port) { 
     //  JSch jsch=new JSch(); 
     try { 
      Session sessionlokal = jsch.getSession(usernamelokal, 
        hostnamelokal, port); 
      sessionlokal.setPassword(password); 
      UserInfo ui = new UserInfoku.Infoku(); 
      sessionlokal.setUserInfo(ui); 
      sessionlokal.setTimeout(0); 
      sessionlokal.connect(); 
      status = "tersambung \n"; 
      username = usernamelokal; 
      hostname = hostnamelokal; 
      session = sessionlokal; 
      System.out.println(username + " " + hostname); 
     } catch (Exception e) { 
      System.out.println(e); 
      status = "Exception = \n " + e + "\n"; 

     } 
    } 

    public void disconnect() { 
     //  JSch jsch=new JSch(); 
     try { 
      Session sessionlokal = jsch.getSession(username, hostname); 
      //   System.out.println(username +" "+ hostname); 
      sessionlokal.disconnect(); 
      status = "wes pedhoott \n"; 
     } catch (Exception e) { 
      System.out.println(e); 
      status = "Exception = \n " + e + "\n"; 
     } 

    } 

    public void addRoute() { 
     //  JSch jsch=new JSch(); 
     System.out.println(username + " " + hostname); 
     try { 
      Session sessionlokal = session; // =jsch.getSession(username, hostname); 
      Channel channel = sessionlokal.openChannel("exec"); 
      ((ChannelExec) channel).setCommand(inputcommand); 
      channel.setInputStream(null); 
      channel.connect(); 
      ((ChannelExec) channel).setErrStream(System.err); 
      InputStream in = channel.getInputStream(); 
      channel.connect(); 

      byte[] tmp = new byte[1024]; 
      while (true) { 
       while (in.available() > 0) { 
        int i = in.read(tmp, 0, 1024); 
        if (i < 0) 
         break; 
        System.out.print(new String(tmp, 0, i)); 
       } 
       if (channel.isClosed()) { 
        System.out.println("exit-status: " 
          + channel.getExitStatus()); 
        break; 
       } 
       try { 
        Thread.sleep(1000); 
       } catch (Exception ee) { 
       } 
      } 

      channel.disconnect(); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 
}  

समस्या है जब मैं कनेक्ट विधि कॉल और फिर addroute बुला, कार्यक्रम रिटर्न

root 192.168.50.2 
root 192.168.50.2 
com.jcraft.jsch.JSchException: session is down 

मैं के साथ सत्र का दर्जा प्राप्त करने की कोशिश कर रहा है या तो

Session sessionlokal=session; //returns com.jcraft.jsch.JSchException: ChannelExec 

या

Session sessionlokal=jsch.getSession(username, hostname); //returns session is down 

मैंने रखरखाव का उपयोग करने की भी कोशिश की है, लेकिन यह काम नहीं कर रहा है।

मेरा इरादा सत्र को छोड़कर, लॉग इन करने के दौरान, कमांड या कमांड निष्पादित करने और बाद में अन्य कमांड निष्पादित करने के लिए सत्र बनाने के लिए सत्र बनाना और फिर सत्र को बंद करना आवश्यक नहीं है (लॉग आउट)। मैं इस मंच पर खोज कर रहा हूं और मुझे यह question मिला है लेकिन कोड पहले निष्पादित करने के लिए कमांड को परिभाषित करने के लिए एक विधि बना रहा है, और फिर सत्र बना रहा है, कमांड की विधि को कॉल करें और सत्र बंद करें।

जैसा ऊपर बताया गया है, इसके बारे में कोई विचार कैसे करें?

उत्तर

4

आप Session#connect() को आमंत्रित करने से पहले निम्नलिखित विधि का आह्वान करके कोशिश कर सकते हैं।

Session#setServerAliveInterval(int milliseconds)

हालांकि मैं एक और समारोह Session#sendKeepAliveMsg() जो करने की कोशिश की जा सकती है, पाया।

10

सफलता के बिना Session.sendKeepAliveMsg() कोशिश कर के बाद, मैं निम्नलिखित समाधान जो बल्कि स्थिर हो रहा है के लिए आया था:

private Session getSession() throws Exception { 
    try { 
     if (!session.isConnected()) { 
      logger.info("Session nicht konnektiert. Versuche (erneut) zu konnektieren."); 
      session.connect(); 
     } 
    } catch (Throwable t) { 
     logger.info("Session kaputt. Baue neue."); 
     session = jsch.getSession(user, host, port); 
     session.setConfig(config); 
     session.connect(); 
    } 
    return session; 
} 

अद्यतन: कुछ दिन बाद यह विफल रहा है।

मैंने सर्वर पर खुले सत्र को मारकर इसका परीक्षण करने की कोशिश की। इस तरह से परीक्षण किए गए सभी पूर्व संस्करणों ने सटीक वही व्यवहार दिखाया, भले ही पहिया समस्या कुछ दिनों तक प्रतीक्षा करने या सर्वर प्रक्रिया को मारने के बाद पॉप अप हो गई, इसलिए मैंने यह परीक्षण सोचा - और उपर्युक्त समाधान के लिए इसका परिणाम - सार्थक होना। दुर्भाग्य से यह नहीं है।

मैं इसे ठीक करने और आपको अद्यतित रखने के कुछ अन्य तरीकों का प्रयास करने जा रहा हूं।

अद्यतन 2: एक उत्पादक वातावरण में

private Session getSession() throws Exception { 
    try { 
     ChannelExec testChannel = (ChannelExec) session.openChannel("exec"); 
     testChannel.setCommand("true"); 
     testChannel.connect(); 
     if(logger.isDebugEnabled()) { 
      logger.debug("Session erfolgreich getestet, verwende sie erneut"); 
     } 
     testChannel.exit(); 
    } catch (Throwable t) { 
     logger.info("Session kaputt. Baue neue."); 
     session = jsch.getSession(user, host, port); 
     session.setConfig(config); 
     session.connect(); 
    } 
    return session; 
} 

इस संस्करण चलाता है कई हफ्तों: अंतिम समाधान, unelegant और काम guarateed। एक दिन में मेरे पास जानकारी संदेश लॉग होता है।

चैनल खोलने और कुछ डू-कमांड कमांड करने की लागत कुछ हद तक परेशान होती है, लेकिन मुझे सत्र की स्थिति के बारे में निश्चित रूप से सुनिश्चित करने का कोई और तरीका नहीं मिला।

+0

अच्छा समाधान, केवल एक संकेत: मैं 'testChannel.exit();' सफल जांच के बाद, 'अन्यथा आप प्रत्येक चेक – GWu

+0

धन्यवाद के लिए अलग-अलग तरफ एक और sftp-server डिमन प्रक्रियाओं के साथ समाप्त होता हूं।जोड़ा गया 'testChannel.exit() '। – blafasel

+0

एकाधिक चैनल खोलते समय मुझे डेडलॉक समस्याएं थीं। GetSession() 'सिंक्रनाइज़' को हल करना इसे हल किया गया है, लेकिन यह एक प्रदर्शन हिट का थोड़ा सा है। क्या आप जानते हैं कि किस भाग को सिंक्रनाइज़ करने की आवश्यकता हो सकती है? शायद टेस्ट चैनल कनेक्ट = डिस्कनेक्ट? –

संबंधित मुद्दे