【问题标题】:How to I get my simple Swing telnet client to display characters correctly?如何让我的简单 Swing telnet 客户端正确显示字符?
【发布时间】:2012-03-09 20:04:09
【问题描述】:

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


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


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

登录:新用户 密码:

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

按任意键继续。


当我使用 putty 连接时,输入我的登录名和密码后,屏幕会清除 以下显示。有什么想法可以达到同样的效果吗?


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

登录:新用户 密码: 欢迎使用美国第一个公共访问 UNIX 系统 M-Net!

M-Net 是由 Arbornet, Inc. 提供的免费访问社区服务, 非营利性安娜堡公司。 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.,

按任意键继续


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


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.
                    }
                }

            }
        }

    }
}

【问题讨论】:

  • 请此代码的 90pct 与您的问题无关,请使用 SSCCE 编辑您的问题
  • 这里有一个更短的工作example 供参考。

标签: java swing client telnet


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 2011-06-07
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2012-02-24
    • 1970-01-01
    相关资源
    最近更新 更多