使用Socket进行对类linux系统的连接和发送命令
2012-08-20 16:07
597 查看
最近在做一个项目需要用java实现用ssh,telnet连接linux然后发送命令。很多种连接方式底层都是使用Socket方式连接的。简单言之,Socket是一个包含了IP address + port number的应用程序接口API,是网络上互连的两个机器上的进程间的通信(communication)的端点。最近在看TCP/IP 协议时对,Socket是建立在传输层上的应用程序的接口。传输层定义的PDU包含了一个端口号。Java
Documentation中关于java.net.Socket的介绍链接:http://docs.oracle.com/javase/tutorial/networking/sockets/definition.html
PS:经过网上查资料了解到SSHv1和SSHv2的协议是互相不兼容的。实现SSHv2连接的Library并不能运行SSHv1的连接。
以下是用java.net.Socket的API实现SocketClient的连接和发送命令。
实现TelnetClient的代码如下:
Documentation中关于java.net.Socket的介绍链接:http://docs.oracle.com/javase/tutorial/networking/sockets/definition.html
PS:经过网上查资料了解到SSHv1和SSHv2的协议是互相不兼容的。实现SSHv2连接的Library并不能运行SSHv1的连接。
以下是用java.net.Socket的API实现SocketClient的连接和发送命令。
public class SocketClient { //========================================================================== // Private variables. //========================================================================== private InetSocketAddress serverAddress; private String newLine; private Socket socket; private PrintWriter writer; private BufferedReader reader; //========================================================================== // Public methods. //========================================================================== public SocketClient(InetSocketAddress serverAddress, String newLine) { this.serverAddress = serverAddress; this.newLine = newLine; socket = null; writer = null; } public void open() throws IOException { socket = new Socket(); socket.connect(serverAddress); writer = new PrintWriter(socket.getOutputStream()); reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); } public void close() { if (writer != null) { writer.close(); writer = null; } if (reader != null) { try { reader.close(); } catch (IOException e) { } reader = null; } if (socket != null) { try { socket.close(); } catch (IOException e) { } socket = null; } } public String send(String cmd, String[] prompts, long timeoutMillis) throws IOException, TimeoutException { // Remove old printouts (if any). clearPrintouts(); // Send command. writer.print(cmd + newLine); writer.flush(); // Read printout. String printoutWithPrompt = readToPrompt(prompts, timeoutMillis); // Remove last line (the prompt). String printoutWithoutPrompt = null; if(printoutWithPrompt.lastIndexOf(newLine)>-1) printoutWithoutPrompt = printoutWithPrompt.substring(0, printoutWithPrompt.lastIndexOf(newLine)); return printoutWithoutPrompt; } public String readToPrompt(String prompt, long timeoutMillis) throws IOException, TimeoutException { String[] prompts = { prompt }; return readToPrompt(prompts, timeoutMillis); } public String readToPrompt(String[] prompts, long timeoutMillis) throws IOException, TimeoutException { StringBuilder printout = new StringBuilder(); // Read printout to next prompt. long startTimeMillis = System.currentTimeMillis(); char[] buffer = new char[2048]; while (true) { if (reader.ready()) { // Read input. int numCharsRead = reader.read(buffer); if (numCharsRead == -1) { // The server socket has been closed. String msg = String.format("Could not read printout: Server socket was closed"); throw new IOException(msg); } // Append to printout. printout.append(buffer, 0, numCharsRead); if (endsWithPrompt(printout, prompts)) { // We have found a prompt. break; } } if (System.currentTimeMillis() > startTimeMillis + timeoutMillis) { // Command timed out. String msg = String.format("Timed out while waiting for prompt"); throw new TimeoutException(msg + " data: |" + printout + "|"); } if (System.currentTimeMillis() > (startTimeMillis + 25000)){ //System.out.println(); } try { Thread.sleep(20); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } return printout.toString(); } public void clearPrintouts() throws IOException { char[] buffer = new char[1024]; while (reader.ready()) { reader.read(buffer); } } private boolean endsWithPrompt(StringBuilder printout, String[] prompts) { for (String prompt : prompts) { if (printout.toString().endsWith(prompt) || endsWithPrompt(printout, prompt)) { return true; } } return false; } private boolean endsWithPrompt(StringBuilder printout, String prompt){ int lastNewLine = printout.lastIndexOf(newLine); if(lastNewLine>0){ if(printout.substring(0, lastNewLine).endsWith(prompt)) return true; } return false; } }
实现TelnetClient的代码如下:
public class PassportTelnetClient implements IClient{ //Data Members public enum CheckType{ EQUAL, MORETHAN, LESSTHAN } //========================================================================== // Private static constants. //========================================================================== private final long defaultTimeoutMillis; private final SocketClient socketClient; private boolean connected = false; private Log logger = LogFactory.getLog(PassportTelnetClient.class); protected String username; protected String password; private static String Passport_PROMPT = "> "; public PassportTelnetClient(String host, int port, long defaultTimeoutMillis) throws UnknownHostException { InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName(host), port); socketClient = new SocketClient(socketAddress, "\r\n"); this.defaultTimeoutMillis = defaultTimeoutMillis; } @Override public void open(String user, String password) throws ConnectException { open(user, password, Passport_PROMPT, "Enter login: ", "Enter password: ", "logged in"); } @Override public void open(String user, String password, String prompt) throws ConnectException { Passport_PROMPT = prompt; } public void open(String user, String password, String prompt, String usernamePrompt, String passwordPrompt) throws ConnectException{ open(user, password, prompt, usernamePrompt, passwordPrompt, null); } public void open(String user, String password, String prompt, String usernamePrompt, String passwordPrompt, String loginOkText) throws ConnectException { try { socketClient.open(); // Login to NODE. socketClient.readToPrompt(usernamePrompt, defaultTimeoutMillis); send(user, passwordPrompt); String result = send(password, prompt); connected = true; if(loginOkText!=null && !result.contains(loginOkText)) throw new CommunicationException("Could not login to node"); } catch (Exception e) { close(); throw new ConnectException("Could not connect to host",e); } } @Override public void close() { socketClient.close(); } @Override public void disconnect() { try { if(connected){ send("exit"); } } catch (CommunicationException e) { // TODO Auto-generated catch block e.printStackTrace(); } close(); } @Override public String send(final String command) throws CommunicationException { return send(command, defaultTimeoutMillis); } @Override public String send(String command, long timeoutMillis) throws CommunicationException{ String printout = send(command, Passport_PROMPT, timeoutMillis); return printout; } protected final String send(String cmd, String prompt) throws CommunicationException { return send(cmd, prompt, defaultTimeoutMillis); } protected final String send(String cmd, String[] prompts) throws CommunicationException { return send(cmd, prompts, defaultTimeoutMillis); } protected final String send(String cmd, String prompt, long timeoutMillis) throws CommunicationException { String[] prompts = { prompt }; return send(cmd, prompts, timeoutMillis); } protected final String send(String cmd, String[] prompts, long timeoutMillis) throws CommunicationException { try { return socketClient.send(cmd, prompts, timeoutMillis); } catch (Exception e) { throw new CommunicationException(e); } } @Override public void connect(String user, String password) throws ConnectException { open(user, password); } }
相关文章推荐
- Linux下检测网卡与网线连接状态,使用ioctl向socket发送SIOCETHTOOL命令字
- Linux下检测网卡与网线连接状态,使用ioctl向socket发送SIOCETHTOOL命令字
- Linux下检测网卡与网线连接状态,使用ioctl向socket发送SIOCETHTOOL命令字
- Linux下检测网卡与网线连接状态,使用ioctl向socket发送SIOCETHTOOL命令字
- Linux下检测网卡与网线连接状态,使用ioctl向socket发送SIOCETHTOOL命令字
- Linux下检测网卡与网线连接状态,使用ioctl向socket发送SIOCETHTOOL命令字
- Linux下检测网卡与网线连接状态,使用ioctl向socket发送SIOCETHTOOL命令字
- C语言中 使用popen函数向linux系统发送shell命令
- Linux系统使用mailx命令发送邮件
- 使用ln命令在Linux系统中创建连接文件
- linux 系统下使用socket进行本地进程间通信
- Linux怎么使用ss命令查看系统的socket状态
- 使用ln命令在Linux系统中创建连接文件
- Linux系统下使用MySQL命令实现远程连接MySQL数据库
- 使用ln命令在Linux系统中创建连接文件
- Redhat系列linux系统安装,并使用xshell工具进行远程连接
- 在mac下使用终端命令通过ssh协议连接远程linux系统,代替windows的putty
- linux 系统下使用socket进行本地进程间通信
- 使用parted命令对linux硬盘进行操作
- 使用ssh无法连接虚拟机linux系统