Почему чтение из вывода канала оболочки в JSch никогда не заканчивается -1? - PullRequest
3 голосов
/ 24 июня 2019

Я создал объект под названием Obj, который отправляет сообщения по каналу Secure Shell. Я могу отправлять символы в UTF-8, что означает, что выходной поток должен обрабатывать многобайтовые символы. Вот почему я решил использовать буферизованный выходной поток записи. Это не имеет значения, поэтому код ссылается только на эту часть кода с комментарием.

Я бы хотел, чтобы входной поток также обрабатывал многобайтовые символы. Я знаю, что функция read () InputStreamReader будет возвращать целые числа, которые соответствуют кодовым точкам 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 голос
/ 24 июня 2019

Канал "shell" открывает оболочку.

Мы не знаем, что на самом деле делает ваш код.Но я предполагаю, что вы отправляете какую-то команду в оболочку для выполнения, а затем пытаетесь прочитать вывод команды.И вы, вероятно, ожидаете получить -1, как только закончится вывод команды. Вы не будете.

Выходной поток оболочки заканчивается, только когда заканчивается оболочка.И для этого вам нужно отправить какую-нибудь команду типа exit.


В общем случае вам не следует использовать канал "shell" .Он предназначен для реализации сеанса интерактивной оболочки (например, если вы реализуете свой собственный терминал SSH).Это то, что вы редко делаете.

Чтобы автоматизировать выполнение команды, используйте канал "exec".

См. Также В чем разница между каналом 'shell' и 'exec'канал в JSch .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...