如何让我的简单Swing telnet客户端正确显示字符?

时间:2012-02-18 22:49:52

标签: java swing client telnet

我正在尝试在Swing中编写一个简单的telnet客户端(类似于Putty)。我有基本功能,但我得到了有趣的转义字符,如“Z [H [J”。我也没有得到像putty那样的内容。


这是我的应用程序显示的内容:


FreeBSD / i386(m-net.arbornet.org)(pts / 15)

登录:NEWUSER  密码:

Z [H [J欢迎使用M-Net America的首个公共访问UNIX系统!

按任意键继续。


当我使用putty连接时,输入我的登录名和密码后,屏幕会清除 以下显示。关于如何实现同样的想法?


FreeBSD / i386(m-net.arbornet.org)(pts / 6)

登录:newuser 密码: 欢迎来到M-Net,这是美国首个公共访问UNIX系统!

M-Net是Arbornet,Inc。提供的免费访问社区服务 非营利性的Ann Arbor公司。使用M-Net是完全免费的 - 享受! 如果您认为M-Net足以成为后来的支持者(M-Net是 由用户贡献支持),在您登录后随时键入“支持” 到系统。感谢您致电M-Net,欢迎光临!

            What's happening here

您好。我是新用户程序。我完全自动化了。我要去教书 关于如何更有效地使用这个系统,你是一个非常小的数量。 然后我会继续问你几个问题。我会给你一个 有机会纠正你的答案,然后我会为你创建一个帐户 (根据你的答案)。在那之后,我已经完成了,我会告诉你 系统与您的新帐户。首先,请允许我再告诉你一些 关于M-Net。

    What is M-Net?

M-Net首先是一个有趣的地方。我们希望您喜欢登录 M-Net - 但M-Net也作为社区资源存在。 Arbornet,Inc。,

按任意键继续


以下是我的应用程序的完整可编译和可运行代码。运行后,单击“连接”(没有密码)以查看我所描述的内容。这将打开一个telnet连接到arbornet.org(一个提供免费shell帐户的站点)作为newuser登录,没有密码。


package ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;

import org.apache.commons.net.telnet.TelnetClient;

public class SwingTelnetClient extends JFrame {
    private static final long serialVersionUID = 1L;
    JLabel lblServer = new JLabel();
    JLabel lblUserId = new JLabel();
    JLabel lblPassword = new JLabel();
    JButton btnConnect = new JButton();
    JButton btnDisconnect = new JButton();
    JTextField txtServer = new JTextField();
    JTextField txtUserId = new JTextField();
    JPasswordField txtPassword = new JPasswordField();
    JLabel lblCommand = new JLabel();
    JTextArea txtConsole = new JTextArea();
    JTextField txtCommand = new JTextField();
    JScrollPane scrollPane = new JScrollPane();

    PrintStream consolePrintStream = null;
    MyTelnetClient client;

    public SwingTelnetClient() {
        setTitle("Simple Telnet Client");

        JPanel panel = createMainPanel();
        addListeners();
        this.setPreferredSize(new Dimension(800, 400));
        this.getContentPane().add(panel);
    }

    private JPanel createMainPanel() {

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        panel.add(createTopPanel(), BorderLayout.NORTH);

        txtConsole.setColumns(50);
        txtConsole.setSize(300, 300);
        txtConsole.setBackground(Color.black);
        txtConsole.setForeground(Color.green);
        txtConsole.setFont(new Font("Terminal", 0, 16));
        txtConsole.setFocusable(false);
        scrollPane.getViewport().add(txtConsole);

        panel.add(scrollPane, BorderLayout.CENTER);
        panel.add(createBottomPanel(), BorderLayout.SOUTH);

        return panel;
    }

    private void addListeners() {
        btnConnect.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                client = new MyTelnetClient(txtServer.getText());

                consolePrintStream = new PrintStream(new FilteredStream(client.getOut()));
                System.setErr(consolePrintStream);
                System.setOut(consolePrintStream);

                client.connect(txtUserId.getText(), txtPassword.getText());

                txtCommand.requestFocus();

            }
        });

        btnDisconnect.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                client.disconnect();
                txtConsole.setText("Disconnected");
                txtUserId.requestFocus();

            }
        });

        txtPassword.addKeyListener(new KeyListener() {

            public void keyTyped(KeyEvent e) {
            }

            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    btnConnect.doClick();
                }
            }

            public void keyPressed(KeyEvent e) {
            }
        });

        txtCommand.addKeyListener(new KeyListener() {

            public void keyTyped(KeyEvent e) {
            }

            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    String command = txtCommand.getText().trim();

                    if (command.equals("exit")) {
                        client.disconnect();
                        txtConsole.setText("Disconnected");
                        txtUserId.requestFocus();
                    } else if (command.equals("clear")) {
                        txtConsole.setText("");
                    } else {
                        client.sendCommand(command);
                    }

                    txtCommand.setText("");
                }
            }

            public void keyPressed(KeyEvent e) {
            }
        });

        txtServer.addFocusListener(new SelectAllFocusListener(txtServer));
        txtUserId.addFocusListener(new SelectAllFocusListener(txtUserId));
        txtPassword.addFocusListener(new SelectAllFocusListener(txtPassword));
    }

    private JPanel createTopPanel() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));
        panel.setPreferredSize(new Dimension(300, 70));

        lblServer.setText("Server");
        lblUserId.setText("User Id");
        lblPassword.setText("Password");

        txtServer.setText("arbornet.org");
        txtUserId.setText("newuser");
        txtPassword.setText("");
        btnConnect.setText("Connect");
        btnConnect.setSize(30, 25);
        btnDisconnect.setText("Disconnect");
        btnDisconnect.setSize(30, 25);

        txtServer.setColumns(20);
        txtUserId.setColumns(15);
        txtPassword.setColumns(15);

        panel.add(lblServer);
        panel.add(txtServer);
        panel.add(lblUserId);
        panel.add(txtUserId);
        panel.add(lblPassword);
        panel.add(txtPassword);
        panel.add(btnConnect);
        panel.add(btnDisconnect);

        return panel;
    }

    private JPanel createBottomPanel() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));

        lblCommand.setText("Execute Command");

        txtCommand.setColumns(50);

        panel.add(lblCommand);
        panel.add(txtCommand);

        return panel;
    }

    public static void main(String[] args) {
        SwingTelnetClient main = new SwingTelnetClient();
        main.pack();
        main.show();
    }

    private void scrollToBottom() {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    int endPosition = txtConsole.getDocument().getLength();
                    Rectangle bottom = txtConsole.modelToView(endPosition);
                    txtConsole.scrollRectToVisible(bottom);
                } catch (BadLocationException e) {
                    System.err.println("Could not scroll to " + e);
                }
            }
        });
    }

    class SelectAllFocusListener implements FocusListener {
        JTextField textField;

        public SelectAllFocusListener(JTextField textField) {
            this.textField = textField;
        }

        public void focusLost(FocusEvent e) {
        }

        public void focusGained(FocusEvent e) {
            textField.selectAll();
        }
    }

    class FilteredStream extends FilterOutputStream {
        public FilteredStream(OutputStream aStream) {
            super(aStream);
        }

        public void write(byte b[]) throws IOException {
            String aString = new String(b);
            txtConsole.append(aString);
        }

        public void write(byte b[], int off, int len) throws IOException {
            String aString = new String(b, off, len);
            txtConsole.append(aString);
            scrollToBottom();
        }
    }

    class MyTelnetClient {

        private static final String ENCODING = "ISO-8859-1";

        private TelnetClient telnet = new TelnetClient();

        private InputStream in;

        private PrintStream out;

        private String prompt = "$";

        ReaderThread readerThread;

        public MyTelnetClient(String server) {

            try {

                // Connect to the specified server

                telnet.connect(server, 23);

                in = telnet.getInputStream();

                out = new PrintStream(telnet.getOutputStream());

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

        }

        public void connect(String user, String password) {
            try {

                readUntil("login:");
                write(user);
                readUntil("Password:");
                write(password);
                startReading();

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

        public String readUntilPrompt() {
            return readUntil(prompt + " ");
        }

        public void startReading() {
            readerThread = new ReaderThread("reader", in);
            readerThread.start();
        }

        public String readUntil(String pattern) {

            try {

                char lastChar = pattern.charAt(pattern.length() - 1);
                StringBuffer sb = new StringBuffer();
                char ch = (char) in.read();

                while (true) {

                    System.out.print(ch);
                    sb.append(ch);

                    if (ch == lastChar) {
                        if (sb.toString().endsWith(pattern)) {
                            return sb.toString();
                        }
                    }

                    ch = (char) in.read();
                }

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

            return null;

        }

        public void disconnect() {

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

        public String sendCommand(String command) {

            try {
                write(command);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        private void write(String value) {

            try {
                out.println(value);
                out.flush();
                System.out.println(value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public InputStream getIn() {
            return in;
        }

        public PrintStream getOut() {
            return out;
        }

        class ReaderThread extends Thread {
            InputStream is;
            boolean keepRunning = true;

            public ReaderThread(String str, InputStream is) {
                super(str);
                this.is = is;
            }

            public void run() {

                while (true) {

                    try {
                        char ch = (char) in.read();
                        System.out.print(ch);
                    } catch (IOException e) {
                        // Swallow intentionally. Don't want stacktrace to
                        // appear in console.
                    }
                }

            }
        }

    }
}

1 个答案:

答案 0 :(得分:0)

您需要解析服务器发送给您的escape codes。这可能有点繁琐,因为你必须在telnet解析的顶部(检测并处理IAC序列等)上单独的解析层,并且没有什么能阻止服务器发送你一次数据一个字节。