使用Socket进行对类linux系统的连接和发送命令

          最近在做一个项目需要用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的连接和发送命令。

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);
	}
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值