为什么从 JSch 中的 shell 通道输出读取永远不会以 -1 结尾?
Why does reading from a shell channel output in JSch never end with -1?
我创建了一个名为 Obj 的对象,它通过安全 Shell 通道发送消息。我可以用 UTF-8 发送字符,这意味着输出流必须处理多字节字符。这就是我决定使用缓冲输出流编写器的原因。那是不相关的,因此代码仅引用带有注释的那部分代码。
我希望输入流也能处理多字节字符。我知道 InputStreamReader 的 read() 函数将 return 对应于 UTF-16 代码点或 -1 的整数。我当前的实现循环并测试 -1。它无休止地循环。为什么?
这是我的源代码:
public class Obj {
public String sendMessage(char[] message) {
final int CONNECTION_TIMEOUT_MILLISECONDS = 300;
final int IN_BUFFER_SIZE = 2048;
int codePoint;
StringBuilder sbResponse = new StringBuilder();
try {
ChannelShell channel = SshChannelFactory.getChannel(this);
if (channel == null) {
System.out.println("Unable to acquire channel for object \"{}\"", this);
throw new RuntimeException();
}
channel.connect(CONNECTION_TIMEOUT_MILLISECONDS);
System.out.println("Successfully opened channel to \"{}\"", channel.getHost());
}
/**
* Write some stuff in this try block.
*/
//try {
//} catch
/**
* Read the response in this try block.
*/
char[] buffer = new char[IN_BUFFER_SIZE];
int bytesReadOffset = 0;
try {
BufferedReader fromServerStream = new BufferedReader(new InputStreamReader(channel.getInputStream(), Charset.forName("UTF-8")), IN_BUFFER_SIZE);
while ((codePoint = fromServerStream.read()) != -1) {
sbResponse.append((char) codePoint);
} catch (IOException e) {
e.printStackTrace();
}
return sbResponse.toString();
}
public class SshChannelFactory {
public static ChannelShell getChannel(Obj obj) {
return createSshChannel(obj);
}
private static Session createSshSession(Obj obj) {
final JSch jsch = new JSch();
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
try {
Session session = jsch.getSession(obj.getUser(), obj.getHost(), obj.getPort());
session.connect();
return session;
} catch (JschException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
private static ChannelShell createSshChannel() {
Session session = SSHSessionFactory.createSshSession(Obj obj)
try {
ChannelShell channel = (ChannelShell) session.openChannel("shell");
channel.setPty(true);
channel.setInputStream(null);
channel.setOutputStream(null);
return channel;
} catch (JSchException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
}
“shell”频道打开 shell。
我们不知道您的代码实际做了什么。但我假设您向 shell 发送了一些命令来执行,然后您尝试读取命令输出。一旦命令输出结束,您可能希望得到 -1。 你不会的。
shell 输出流结束,仅当 shell 结束时。为此,您需要发送一些命令,例如 exit
.
一般来说,您不应使用“shell”频道。它旨在实现交互式 shell 会话(就像您正在实现自己的 SSH 终端一样)。那是你很少做的事情。
要自动执行命令,请使用“exec”通道。
另见 What is the difference between the 'shell' channel and the 'exec' channel in JSch。
我创建了一个名为 Obj 的对象,它通过安全 Shell 通道发送消息。我可以用 UTF-8 发送字符,这意味着输出流必须处理多字节字符。这就是我决定使用缓冲输出流编写器的原因。那是不相关的,因此代码仅引用带有注释的那部分代码。
我希望输入流也能处理多字节字符。我知道 InputStreamReader 的 read() 函数将 return 对应于 UTF-16 代码点或 -1 的整数。我当前的实现循环并测试 -1。它无休止地循环。为什么?
这是我的源代码:
public class Obj {
public String sendMessage(char[] message) {
final int CONNECTION_TIMEOUT_MILLISECONDS = 300;
final int IN_BUFFER_SIZE = 2048;
int codePoint;
StringBuilder sbResponse = new StringBuilder();
try {
ChannelShell channel = SshChannelFactory.getChannel(this);
if (channel == null) {
System.out.println("Unable to acquire channel for object \"{}\"", this);
throw new RuntimeException();
}
channel.connect(CONNECTION_TIMEOUT_MILLISECONDS);
System.out.println("Successfully opened channel to \"{}\"", channel.getHost());
}
/**
* Write some stuff in this try block.
*/
//try {
//} catch
/**
* Read the response in this try block.
*/
char[] buffer = new char[IN_BUFFER_SIZE];
int bytesReadOffset = 0;
try {
BufferedReader fromServerStream = new BufferedReader(new InputStreamReader(channel.getInputStream(), Charset.forName("UTF-8")), IN_BUFFER_SIZE);
while ((codePoint = fromServerStream.read()) != -1) {
sbResponse.append((char) codePoint);
} catch (IOException e) {
e.printStackTrace();
}
return sbResponse.toString();
}
public class SshChannelFactory {
public static ChannelShell getChannel(Obj obj) {
return createSshChannel(obj);
}
private static Session createSshSession(Obj obj) {
final JSch jsch = new JSch();
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
try {
Session session = jsch.getSession(obj.getUser(), obj.getHost(), obj.getPort());
session.connect();
return session;
} catch (JschException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
private static ChannelShell createSshChannel() {
Session session = SSHSessionFactory.createSshSession(Obj obj)
try {
ChannelShell channel = (ChannelShell) session.openChannel("shell");
channel.setPty(true);
channel.setInputStream(null);
channel.setOutputStream(null);
return channel;
} catch (JSchException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
}
“shell”频道打开 shell。
我们不知道您的代码实际做了什么。但我假设您向 shell 发送了一些命令来执行,然后您尝试读取命令输出。一旦命令输出结束,您可能希望得到 -1。 你不会的。
shell 输出流结束,仅当 shell 结束时。为此,您需要发送一些命令,例如 exit
.
一般来说,您不应使用“shell”频道。它旨在实现交互式 shell 会话(就像您正在实现自己的 SSH 终端一样)。那是你很少做的事情。
要自动执行命令,请使用“exec”通道。
另见 What is the difference between the 'shell' channel and the 'exec' channel in JSch。