有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么从JSch中的shell通道输出读取永远不会以1结束?

我创建了一个名为Obj的对象,它通过一个安全的Shell通道发送消息。我可以用UTF-8发送字符,这意味着输出流必须处理多字节字符。这就是我决定使用缓冲输出流编写器的原因。这是不相关的,因此代码只引用代码中带有注释的部分

我希望输入流也能处理多字节字符。我知道InputStreamReader的read()函数将返回与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();
        }
    }
}

共 (1) 个答案

  1. # 1 楼答案

    “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