您的位置:首页 > 运维架构 > Linux

使用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的连接和发送命令。

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: