java.io包里有两个关于管道传输的类,PipedInputStream和PipedOutputStream,它们可以看做是一个传输管道的两端,PipedOutputStream是发送端(入口),用write和flush方法向管道中“推”数据,PipedInputStream是接收端(出口),用read方法接收数据,构造这样一个管道的通常做法是:
PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream(out);
站在管道的角度看,将入口叫做"output"是一件很诡异的事,因此我估计java的开发者是站在管道使用者的角度命名,向管道里送数据是output,从管道里读数据是input吧。
如果这个管道只传输字符,还可以用java.io里的PipedReader和PipedWriter,使用方法与上述stream类相似。
apache sshd的ClientChannel类的setIn方法需要一个InputStream参数,而PipedInputStream是InputStream的子类,这样我们就可以用下面的方法向SshClient发送数据了:
SshClient client = SshClient.setUpDefaultClient();
client.start();
ClientSession session = client.connect("10.0.2.47", 22).await().getSession();
session.authPassword("user", "password").await().isSuccess();
ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
// 到这里ssh client完成了登录动作
PipedOutputStream out = new PipedOutputStream();
channel.setIn(new PipedInputStream(out));
// 这两句建立了一个 pipedOut -> pipedIn -> ssh client的数据管道,下面就可以用write方法给client发数据了
ByteArrayOutputStream output = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
channel.setOut(output);
channel.setErr(err);
channel.open();
// 到此连接通道已打开,可以接收指令了
pipedIn.write("pwd\n".getBytes());
pipedIn.flush();
// 向client发送指令
String res = output.toString("UTF-8");
// 获取client收到的报文
output.reset();
// 清空接收缓存