Telnet Java Socket 测试

3
我需要一些指导。不确定我是否走上了正确的道路,但我认为是的。我正在尝试创建一个telnet java程序,它将连接到客户端计算机,执行单个命令,然后断开连接。当我连接到Linux机器或我的路由器时,我能够使程序工作并将InputStream读取到文本字段中(用于测试目的)。但当我连接到Windows机器或其他客户端计算机时,它就无法正常工作。它会读取一些随机字符,然后锁定。
以下是我的代码。我已经看到了其他代码示例以及来自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();
}
}

    }

你怎么知道你所获得的数据是错误的?可能是某种身份验证数据。你能提供给我们输出吗?另外,你尝试过什么? - Ryan Amos
从我所读的来看,你是对的。这只是认证数据而已。我的问题是,当我尝试连接到Windows系统时,它无法进一步进行。该程序在Linux和我的路由器上运行得很好。 - itgeek25
3个回答

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

恭喜修复成功。当你有时间的时候,请将你的答案标记为“已接受”,以帮助其他人找到解决方案。干杯~ - Andrew Kozak

2

Telnet并不只是一个原始的套接字,发送控制代码(双向)需要解释。

与其自己尝试解释,使用现有的Java Telnet客户端库会更好,比如Apache Commons Net中的库。


我也尝试在Windows系统上使用Apache代码。同样的问题,Linux可以运行但是我的Windows机器不行。我使用了别人用Java编写的应用程序,它很好地运行。我将我的代码与他们的进行了比较,虽然有些细微差异,但输入和输出方式是一样的。他们的代码可以运行,而我的却不能。这就是为什么我快要抓狂了。 - itgeek25
TelnetClient类本身主要用于自动化访问telnet资源,而不是交互式使用。这个链接(http://svn.apache.org/repos/asf/commons/proper/net/tags/NET_1_0_0/src/java/examples/weatherTelnet.java)提供的库在我看来并不实用。 - Thufir

1
如果你看到的“随机字符”以0xFF字节开头,那么它们是Telnet协议命令。
但你还有另一个问题。不要在事件线程中执行长时间运行或阻塞操作。请使用单独的线程。

我尝试创建一个新线程,在不同的进程中运行写入和读取代码。但问题仍然存在,这让我感到困惑。我没有收到任何错误或问题的提示,只是在尝试连接到Windows时出现了卡住的情况。Telnet 在我要连接的 Windows 机器上可以正常工作。 - itgeek25
@itgeek25 你的代码假设每次读取都是一整行。请使用readLine()并确保这一点。 - user207421
请注意,尽管使用单独的线程绝对是必需的,但它不会解决'随机'字符问题。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接