我正在尝试在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.
}
}
}
}
}
}
答案 0 :(得分:0)
您需要解析服务器发送给您的escape codes。这可能有点繁琐,因为你必须在telnet解析的顶部(检测并处理IAC
序列等)上单独的解析层,并且没有什么能阻止服务器发送你一次数据一个字节。