Как мне заставить мой простой клиент Swing telnet правильно отображать символы? - PullRequest
0 голосов
/ 19 февраля 2012

Я пытаюсь написать простой клиент telnet на Swing (похожий на Putty).У меня работает базовая функциональность, но я получаю забавные экранирующие символы, такие как «Z [H [J» ».Я также не получаю содержимое экрана, как замазка.


Вот что отображает мое приложение:


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

login:Пароль нового пользователя:

Z [H [J Добро пожаловать в первую в США систему UNIX общего доступа Америки!

Нажмите любую клавишу для продолжения.


Когда яподключиться с помощью замазки, после ввода моего логина и пароля, экран очищает следующие отображения.Любые мысли о том, как я могу добиться того же?


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

логин: newuser Пароль: Добро пожаловать в M-Net, первая в Америке общедоступная UNIX-система!

M-Net - это бесплатная служба сообщества, предоставляемая Arbornet, Inc., некоммерческой корпорацией Ann Arbor.Использование M-Net абсолютно бесплатно - наслаждайтесь!Если вы решите, что вам нравится M-Net, чтобы в дальнейшем поддерживать его (M-Net поддерживается за счет вкладов пользователей), введите «support» в любое время после входа в систему.Спасибо, что позвонили в M-Net, и добро пожаловать!

            What's happening here

Привет.Я новичок в программе.Я полностью автоматизирован.Я собираюсь научить вас очень мало о том, как использовать эту систему более эффективно.Тогда я собираюсь двигаться дальше и задать вам несколько вопросов.Я дам вам возможность исправить ваши ответы, а затем я создам для вас учетную запись (на основе ваших ответов).После этого я закончу и позволю вам войти в систему с вашей новой учетной записью.Во-первых, позвольте мне рассказать вам немного больше о M-Net.

    What is M-Net?

M-Net, в первую очередь, забавное место.Мы надеемся, что вам понравится входить в M-Net, но M-Net также существует как ресурс сообщества.Arbornet, Inc.,

Нажмите любую клавишу для продолжения


Ниже приведен полный скомпилированный и запускаемый код для моего приложения.После запуска нажмите «Подключиться» (без пароля), чтобы увидеть то, что я описал.Это откроет telnet-соединение с arbornet.org (сайт, который предоставляет бесплатные учетные записи оболочки), когда вы входите в систему как 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 голосов
/ 20 февраля 2012

Вам нужно будет проанализировать escape-коды , которые сервер отправляет вам.Это может быть немного неудобно, потому что вы должны будете сделать это как отдельный слой синтаксического анализа поверх вашего синтаксического анализа telnet (который обнаруживает и обрабатывает последовательности IAC и тому подобное), и ничто не останавливает сервер, отправляющий вам данныеодин байт за раз.

...