2012-03-13 99 views
2

我需要一些方向。不知道我是否在正確的道路上,但我認爲如此。我正在嘗試創建一個連接到客戶端機器的telnet java程序,執行單個命令然後斷開連接。當我連接到Linux機器或我的路由器時,我能夠使程序工作並將InputStream讀出到文本字段(用於測試目的)。但是,當我連接到Windows機器或其他客戶端計算機時,它不起作用。它讀出一些隨機字符,然後鎖定。的Telnet Java Socket技術測試

以下是我的代碼。我已經看到了其他代碼的例子以及來自Apache的API。我真的很想看看我能否只用Java套接字來工作。

public class TestSockets extends JFrame implements ActionListener { 

/** 
* @param args 
*/ 
private String USER = "User"; 
private String PASS = "Password01"; 
private final static String CMD = "exit\r\n"; 
private static Socket telnet = null; 
private PrintWriter writer = null; 
private static InputStream reader = null; 
private String host = "192.168.1.1"; 
private int port = 23; 
TextArea javatext; 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    new TestSockets().setVisible(true); 
} 

private TestSockets() { 
    super("Testing Buttons"); 

    //Set JFrame size 
    setSize(500, 600); 

    //Gives JFrame a location 
    setLocation(100, 100); 

    //set layout 
    setLayout(new FlowLayout()); 

    javatext = new TextArea(25, 65); 

    add(javatext); 

    //Ask for window decorations provided by the look and feel. 
    JFrame.setDefaultLookAndFeelDecorated(true); 
    JButton button3 = new JButton("Run Program"); 
    button3.addActionListener(this); 
    add(button3); 
} 

@Override 
public void actionPerformed(ActionEvent arg0) { 
    // TODO Auto-generated method stub 
    try { 
     telnet = new Socket(host, port); 
     telnet.setKeepAlive(true); 
     //reader = telnet.getInputStream(); 
     writer = new PrintWriter(telnet.getOutputStream()); 
     reader = telnet.getInputStream(); 
     //out = telnet.getOutputStream(); 
     //Process p = Runtime.getRuntime().exec("telnet " + server.toString(), null, null); 
     //DataOutputStream os = new DataOutputStream(p.getOutputStream()); 
     //DataInputStream in = new DataInputStream(p.getInputStream()); 

     StringBuilder sb = new StringBuilder(); 
     byte[] buffer = new byte[4096]; // Read 4K characters at a time 
     int len; // How many chars read each time 
      while ((len = reader.read(buffer)) != -1) { 
      String readchar = new String(buffer, 0, len); 
      sb.append(readchar + "\n"); 
      System.out.println(readchar); 
      javatext.append(readchar); 
      if (readchar.endsWith("login: ")) { 
       writer.print(USER + "\r\n"); 
       writer.flush(); 
      } 
      if (readchar.endsWith("Password: ")) { 
       writer.print(PASS + "\r\n"); 
       writer.flush(); 
      } 
      if (readchar.endsWith("password: ")) { 
       writer.print(PASS + "\r\n"); 
       writer.flush(); 
      } 
      if (readchar.endsWith("# ")) { 
       writer.print(CMD); 
       writer.flush(); 
      } 
      if (readchar.endsWith("# ")) { 
       writer.print(CMD); 
       writer.flush(); 
      } 

     }   
} catch (SocketException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace();  
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
} 

    } 
+0

你怎麼知道什麼你得到居然是壞的數據?您可能會獲得某種認證數據。你能向我們提供輸出嗎?另外,你有什麼嘗試?從我讀到的 – 2012-03-13 23:49:43

+0

,你是對的。這只是驗證數據。我的問題是,當我嘗試連接到Windows盒子時,它並沒有進一步發展。該程序適用於Linux和我的路由器。 – itgeek25 2012-03-14 14:23:54

回答

3

感謝大家的幫助。我真的試圖讓這個在Android中工作,但只是在直接的Java應用程序中做出了一個粗略的草案。我有粗略的想法,它的工作原理。如果我讀取輸出,它會一遍又一遍地重複我的StringBuilder中的所有字符。不是一個大問題,我不是真的要顯示輸出。這是我完成的。希望這可以幫助任何人,如果需要。

public class AndroidSocket extends Activity implements OnClickListener { 

TextView text; 
EditText edit1, edit2, edit3, edit4; 
private String USER = null; 
private String PASS = null; 
Editable server, username, password, command; 
private String CMD = null; 
private PrintStream writer = null; 
private static BufferedReader reader = null; 
private String host = null; 
private int port = 23; 
private TelnetClient telnet = new TelnetClient(); 
private InputStream in; 
private PrintStream out; 
StringBuffer sb; 
Handler mHandler = new Handler(); 
int len; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    text = (TextView)findViewById(R.id.text); 
    edit1 = (EditText)findViewById(R.id.edit1); 
    edit2 = (EditText)findViewById(R.id.edit2); 
    edit3 = (EditText)findViewById(R.id.edit3); 
    edit4 = (EditText)findViewById(R.id.edit4); 

    server = edit1.getEditableText(); 
    username = edit2.getEditableText(); 
    password = edit3.getEditableText(); 
    command = edit4.getEditableText(); 

    Button button = (Button)findViewById(R.id.button); 
    button.setOnClickListener(this); 
    text.setText("Android Socket" + "\n"); 
    } 

@Override 
public void onClick(View arg0) { 
    // TODO Auto-generated method stub 
    text.setText("Android Socket" + "\n"); 
    try { 
     telnet.connect(server.toString(), 23); 
     in = telnet.getInputStream(); 
     out = new PrintStream(telnet.getOutputStream()); 
     reader = new BufferedReader(new InputStreamReader(telnet.getInputStream())); 
     writer = new PrintStream(telnet.getOutputStream()); 
    telnet.setKeepAlive(true); 
    Thread mThread = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      try { 
       sb = new StringBuffer(); 
       //char[] buffer = new char[1024]; 
        while (true) 
        { 
          len = in.read(); 
          String s = Character.toString((char)len); 
          sb.append(s); 
          AndroidSocket.this.mHandler.post(new Runnable(){ 

           @Override 
           public void run() { 
            // TODO Auto-generated method stub 
            AndroidSocket.this.text.getText(); 
            AndroidSocket.this.text.append(sb.toString()); 
           } 

          }); 
          System.out.println(sb); 
          mylogin(); 
          mypass(); 
          mycommand(); 
         } 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
     } 

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

    private void mycommand() throws IOException { 
      // TODO Auto-generated method stub 
if (sb.toString().endsWith("> ")) { 
    out.println(command.toString() + "\r\n"); 
    out.flush(); 
    out.println("exit\r\n"); 
    out.flush(); 
    try { 
     TimeUnit.SECONDS.sleep(10); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    disconnect(); 
} else 
if (sb.toString().endsWith("# ")) { 
    out.println(command.toString() + "\r\n"); 
    out.flush(); 
    out.println("exit\r\n"); 
    out.flush(); 
    try { 
     TimeUnit.SECONDS.sleep(10); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    disconnect(); 
} 
} 

    private void mypass() { 
    // TODO Auto-generated method stub 
if (sb.toString().endsWith("Password: ")) { 
    out.println(password.toString() + "\r\n"); 
    out.flush(); 
} else 
if (sb.toString().endsWith("password: ")) { 
    out.println(password.toString() + "\r\n"); 
    out.flush(); 
} 
} 

    private void mylogin() { 
    // TODO Auto-generated method stub 
if (sb.toString().endsWith("login: ")) { 
    out.println(username.toString() + "\r"); 
    out.flush(); 
} 
} 

     public void disconnect() { 
    try { 
in.close(); 
out.close(); 
telnet.disconnect(); 

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

恭喜上的修補程序。如果可以,請將您的答案標記爲「已接受」,以幫助他人找到您的解決方案。乾杯〜 – 2012-03-16 17:46:35

1

如果您看到的'隨機字符'開頭是0xFF字節,那麼它們是Telnet協議命令。

但你有另一個問題。不要在事件線程中執行長時間運行或阻塞操作。使用一個單獨的線程。

+0

我曾嘗試創建一個新線程,並在單獨的進程中運行寫入和讀取代碼。仍然是同樣的問題。這是我腦海中浮現的東西。我不會得到任何錯誤或問題,它只是試圖連接到Windows時掛起。 Telnet在我嘗試使用的Windows機器上工作。 – itgeek25 2012-03-14 14:25:29

+0

@ itgeek25您的代碼假定每個讀取都是整行。使用readLine()並確保。 – EJP 2012-03-14 23:19:08

+0

@ itgeek25請注意,雖然使用單獨的線程是絕對必需的,但它不會解決「隨機」字符問題。 – EJP 2012-09-08 14:44:48

2

Telnet是不單純是一個原始套接字,有送送(每個方向),你需要解釋的控制代碼。

而不是試圖做自己,你會更好使用現有的Java Telnet客戶端庫像在Apache Commons Net

+0

我試圖在窗口框上使用Apache代碼。同樣的問題,適用於Linux而不是我的Windows機器。我用Java編寫的應用程序,這個工程很好。我將我的代碼與他們的代碼進行了比較,它們略有不同,但讀取輸入和輸出相同。他們的作品,但我的不。這就是爲什麼我拔出我餘下的頭髮。 – itgeek25 2012-03-14 14:28:00

+0

「本身使用的TelnetClient類主要用於自動訪問Telnet資源,而不是交互式使用。」 http://svn.apache.org/repos/asf/commons/proper/net/tags/NET_1_0_0/src/java/examples/weatherTelnet.java不是一個有用的庫,恕我直言 – Thufir 2013-09-14 08:03:44