2016-04-11 6 views
0

Meine Anforderung ist es, eine Verbindung zu einem Server über Telnet mit einem Java-Programm und führen Sie einige Befehle und lesen Sie die Antworten. Auf der Grundlage dieser Antworten brauche ich eine OperationAutomatisierte Telnet-Client mit commons-net

ich mit https://stackoverflow.com/a/1213188/1025328

Ich bin mit commons-net und mein Programm ist so etwas wie dieses strated auszuführen: die Telnet-Verbindung

public class TelnetSample { 
    private TelnetClient telnet; 
    private InputStream in; 
    private PrintStream out; 

    public TelnetSample(String server, int port) { 
     try { 
      // Connect to the specified server 
      telnet = new TelnetClient(); 
      telnet.connect(server, port); 

      in = telnet.getInputStream(); 
      out = new PrintStream(telnet.getOutputStream()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public String readResponse() { 
     System.out.println("TelnetSample.readResponse()"); 

     StringBuilder out = new StringBuilder(); 

     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       out.append(line); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     System.out.println(out.toString()); 
     System.out.println("=========================================================="); 

     return out.toString(); 
    } 

    public String read2() { 
     System.out.println("TelnetSample.read()"); 

     StringBuffer sb = new StringBuffer(); 

     try { 
      int available = in.available(); 

      for (int index = 0; index < available; index++) { 
       char ch = (char) in.read(); 
       System.out.print(ch); 
       sb.append(ch); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return sb.toString(); 
    } 

    public String sendCommand(String command) { 
     try { 
      InputStream is = new ByteArrayInputStream(command.getBytes()); 

      int ch; 

      while ((ch = is.read()) != -1) { 
       out.write(ch); 
       out.flush(); 
      } 

      System.out.println(command); 

      String output = read2(); 

      if (output.trim().isEmpty()) { 
       System.out.println("output empty"); 
      } else { 
       System.out.println(output); 
      } 

      System.out.println("=========================================================="); 

      return output; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    public void disconnect() { 
     try { 
      telnet.disconnect(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     try { 
      TelnetSample telnet = new TelnetSample("aspmx2.xxxxxx.com", 25); 
      telnet.readResponse(); 

      telnet.sendCommand("Helo hi"); 
      telnet.sendCommand("mail from:[email protected]"); 
      telnet.sendCommand("rcpt to:[email protected]"); 
      telnet.sendCommand("quit"); 

      telnet.disconnect(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
Hier auseinander

bilden Antwort, für jeden anderen sendCommand bekomme ich eine leere Antwort. Kann mir jemand zeigen, was das Problem sein könnte?

Meine Ausgabe ist so etwas wie dies

TelnetSample.readResponse() 
220 mx.xxxxxx.com ESMTP o86si4086625pfi.217 - gsmtp 
========================================================== 
Helo hi 
TelnetSample.read() 
output empty 
========================================================== 
mail from:[email protected] 
TelnetSample.read() 
output empty 
========================================================== 
rcpt to:[email protected] 
TelnetSample.read() 
output empty 
========================================================== 
quit 
TelnetSample.read() 
output empty 
========================================================== 

Antwort

0

Es ist möglich, READ2 wird einen Nullwert zurück aus dem Eingangsstrom bekommen, bevor Daten tatsächlich zurückgeführt werden. so etwas wie dieses versuchen:

private String read2() { 

    StringBuffer sb = new StringBuffer(); 

    try { 
     do { 
      if (in.available() > 0) { 
       char ch = (char) in.read(); 
       sb.append(ch); 
      } else { 
       Thread.sleep(1000); 
      } 
     } while (in.available()>0); 

     String output = new String(sb); 
     return output; 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return null; 

} 
0

Dieser Code hat mehrere Ausgabe:

  • die erste Ausgabe in readResponse Methode. Wenn Sie readLine() verwenden, können Sie Ihren Code einfach blockieren und werden ewig warten. Bitte werfen Sie einen Blick auf die Diskussion How to determine the exact state of a BufferedReader?
  • die Sekunde, die Sie keine CR/LF Zeichen senden. Server hat Ihre Anfragen wie eine einzige Zeile. Ex:

Mail von: [email protected] zu: [email protected]

Zum ersten Problem beheben Sie mehrere Möglichkeiten wählen:

  • Mehrzweck Threading Modell
  • verwenden NIO API. Ich würde Netty dafür empfehlen. Speziell für Ihren Fall, da ich sehe, dass Sie überhaupt kein Telnet-Protokoll verwendet haben, haben Sie sich mit dem SMTP-Server verbunden.

Quick Fix aber das Schlimmste, warten erste Zeile vom Server und gehen Sie auf:

public String readResponse() { 
    System.out.println("TelnetSmtpSample.readResponse()"); 
    StringBuilder out = new StringBuilder(); 
    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
     out.append(reader.readLine()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    System.out.println(out.toString()); 
    System.out.println("====================="); 

    return out.toString(); 
} 

zweite zu beheben:

telnet.sendCommand("Helo hi\r\n"); 
    telnet.sendCommand("mail from:[email protected]\r\n"); 
    telnet.sendCommand("rcpt to:[email protected]\r\n"); 
    telnet.sendCommand("quit\r\n");