Что вам нужно знать:
"\r"
) line line (LF - в строковых литералах, представленных как "\n"
) System.in
, который читается Scanner
), также отправляет зависимые от ОС разделители строк (например, для Windows \r\n
) после этого. Поэтому, когда вы запрашиваете у пользователя значение типа age
, а пользовательские типы 42 и нажатия вводятся, стандартный ввод будет содержать "42\r\n"
. Scanner#nextInt
(и другие методы Scanner#nextType
) не позволяют сканеру потреблять эти разделители строк. Он прочитает их из System.in
(как еще Сканер знал бы, что больше нет цифр от пользователя, которые представляют age
значение, чем перед пробелом?), Который удалит их со стандартного ввода, но он также будет кешем эти разделители строк внутри. Нам нужно помнить, что все методы Scanner всегда сканируются, начиная с кэшированного текста.
Теперь Scanner#nextLine()
просто собирает и возвращает все символы , пока не найдет разделители строк (или конец потока). Но поскольку разделители строк после прочтения номера из консоли сразу обнаруживаются в кеше сканера, он возвращает пустую строку, что означает, что сканер не смог найти символ до этих разделителей строк (или конца потока). BTW nextLine
также потребляет эти разделители строк.
Поэтому, когда вы хотите запросить номер, а затем для всей строки и избежать этой пустой строки в результате nextLine
, либо
nextInt
поместить дополнительный nextLine
вызов, чтобы использовать разделители строк из кеша сканеров, nextInt
(ни next
, ни любое nextTYPE
] методов). Вместо этого прочитайте целые строки данных по строке nextLine
и номера разбора из каждой строки (при условии, что одна строка содержит только одно число) для правильного типа, например int
через Integer.parseInt
. BTW: Scanner#nextType
методы могут пропускать разделители (по умолчанию все пробелы, такие как вкладки, разделители строк), в том числе кэшированные сканером, пока они не найдут следующее значение без разделителя (токен). Благодаря этому для ввода типа "42\r\n\r\n321\r\n\r\n\r\nfoobar"
код
int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();
сможет правильно назначить num1=42
num2=321
name=foobar
.
Вы пытаетесь пропустить проверку ключа хоста, установив StrictHostKeyChecking
на no
.
Но вы должны сделать это перед проверкой, то есть перед session.connect()
.
В любом случае, вы никогда не должны этого делать, если вам не нужна безопасность. Проверка ключа хоста защищает вас от атак man-in-the-middle .
Вместо этого настройте ожидаемый ключ хоста, чтобы JSch проверил его.
Например:
JSch.setKnownHosts
, обеспечивающий путь к файлу .ssh/known_hosts
. Для генерации .ssh/known_hosts
-подобного файла вы можете использовать команду ssh-keyscan
из OpenSSH. Если вы подключаетесь к серверу * nix, вы должны иметь доступную команду, просто запустите ssh-keyscan example.com > known_hosts
. Он будет иметь формат, такой как: example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0hVqZOvZ7yWgie9OHdTORJVI5fJJoH1yEGamAd5G3werH0z7e9ybtq1mGUeRkJtea7bzru0ISR0EZ9HIONoGYrDmI7S+BiwpDBUKjva4mAsvzzvsy6Ogy/apkxm6Kbcml8u4wjxaOw3NKzKqeBvR3pc+nQVA+SJUZq8D2XBRd4EDUFXeLzwqwen9G7gSLGB1hJkSuRtGRfOHbLUuCKNR8RV82i3JvlSnAwb3MwN0m3WGdlJA8J+5YAg4e6JgSKrsCObZK7W1R6iuyuH1zA+dtAHyDyYVHB4FnYZPL0hgz2PSb9c+iDEiFcT/lT4/dQ+kRW6DYn66lS8peS8zCJ9CSQ==
И ссылается на сгенерированный файл known_hosts
в вашем JSch-коде. Если вы находитесь в Windows, вы можете получить сборку Windows из проекта Win32-OpenSSH или Git для Windows. JSch.getHostKeyRepository().add()
, чтобы обеспечить ожидаемый ключ хоста (например, жестко запрограммированные, как и другие учетные данные). См. Создание экземпляра JSch HostKey из открытого ключа в формате .pub . Кроме того: «Cygwin», я предполагаю, что вы имеете в виду sshd или sftpd, потому что сам Cygwin не выполняет SSH.
В любом случае, если вы хотите, чтобы клиент Jsch принимал любой ключ от хоста, переместите .setConfig
, который устанавливает StrictHostKeyChecking no
так, как раньше session.connect()
. В качестве альтернативы вы должны предоставить доступ к хранилищу, содержащему правильный ключ (ы) для ваших хостов (ов), как объясняет @Martin, - и вы всегда должны делать это при подключении к чему-либо, кроме «localhost» или, возможно, к машине, тот же физически защищенный сегмент сети (например, проводной сетевой концентратор в одной комнате).