Инструменты Java SSH: ошибка SftpClient: удаленный компьютер отключен: ошибка протокола: слишком длинный пакет: 65580 - PullRequest
1 голос
/ 27 октября 2009

Я получаю сообщение "INFO: удаленный компьютер отключен: ошибка протокола: слишком длинный пакет: 65580" ошибка при попытке выполнить:

sUpload("server.host.com", "username", "/home/localuser/.ssh/id_rsa", "filename", "");

Файл не передается на SFTP-сервер (с другой стороны создается только нулевой байт). Когда SFTPing вручную через оболочку Unix, все работает нормально. Я читал в Интернете, что это может быть проблема с BLOCK_SIZE в SftpClient, но сначала я не смог найти метод установки для изменения размера, а во-вторых, похоже, что значение по умолчанию равно 65535, что полностью не объясняет значение 65580 из ошибки сообщение.

Есть идеи?

У меня есть следующий служебный метод, который использует Java Ssh Tools (j2ssh-core-0.2.9.jar):

private static void sUpload(String ftpServer, String user, String password,
String localFile, String remoteFile) throws IOException {
    String methodName = "sUpload: ";
    System.out.println(" START ftpServer="+ftpServer+" user="+user+" password="+password);

    int result = 0;
    System.out.println("ftpServer " + ftpServer);
    System.out.println("user  " + user);
    System.out.println("password  " + password);
    System.out.println("localFile " + localFile);
    System.out.println("remoteFile    " + remoteFile);

    SshClient ssh = new SshClient();

    ssh.connect(ftpServer);

    System.out.println("Server Connected  ");
    if (password.contains("\\") || password.contains("/")) {

        PublicKeyAuthenticationClient pk = 
            new PublicKeyAuthenticationClient();

        pk.setUsername(user);
        // Open up the private key file
        SshPrivateKeyFile file = SshPrivateKeyFile
                .parse(new File(password));
        SshPrivateKey key = file.toPrivateKey(null);
        pk.setKeyfile(password);
        pk.setKey(key);
        // Try the authentication
        result = ssh.authenticate(pk);

    } else {

        // Create a password authentication instance
        PasswordAuthenticationClient pwd = 
            new PasswordAuthenticationClient();
        // Get the users name
        pwd.setUsername(user);
        // Get the password
        pwd.setPassword(password);

        // Try the authentication
        result = ssh.authenticate(pwd);
    }

    System.out.println("Result fromssh.authenticate(pwd) " + result);
    // Evaluate the result
    if (result == AuthenticationProtocolState.COMPLETE) {

        // The connection is authenticated we can now do some real work!
        SftpClient sftp = ssh.openSftpClient();       
        System.out.println("openSftpClient");
        // Upload a file
        if(remoteFile != null && remoteFile.trim().length() > 0){
            sftp.put(localFile, remoteFile);
            System.out.println("======== no remote ======================================== file transfer success =======================================================================");
        }
        else    {
            System.out.println("================================================ file transfer starting =======================================================================");
            sftp.put(localFile);
            System.out.println("================================================ file transfer success =======================================================================");
        }


        // Quit
        sftp.quit();
        ssh.disconnect();
    }
    System.out.println(" END ");
}

Ответы [ 3 ]

1 голос
/ 27 октября 2009

ssh-клиент должен сообщить серверу, каков максимальный размер пакета, и сервер должен соответствовать спецификациям.

Попробуйте использовать другой сервер и проверьте настройку максимального размера пакета вашего собственного сервера.

1 голос
/ 27 октября 2009

Похоже, работает следующий код - я использовал более низкий уровень "com.sshtools.j2ssh.sftp.SftpSubsystemClient" вместо "com.sshtools.j2ssh.SftpClient" и чтения / записи файлов с использованием потоков ввода / вывода:

    System.out.println("Result fromssh.authenticate(pwd) " + result);
    // Evaluate the result
    if (result == AuthenticationProtocolState.COMPLETE) {
        SftpSubsystemClient sftpSubsystemClient = ssh.openSftpChannel();
        com.sshtools.j2ssh.connection.Channel sftpChannel = sftpSubsystemClient;
        System.out.println("Local packet size: " + sftpChannel.getLocalPacketSize());
        System.out.println("Remote packet size: " + sftpChannel.getRemotePacketSize());

        SftpFile file = sftpSubsystemClient.openFile(remoteFile, SftpSubsystemClient.OPEN_CREATE | SftpSubsystemClient.OPEN_WRITE);

        FileAttributes attrs = file.getAttributes();
        attrs.setPermissions("rwxrwxrwx");
        sftpSubsystemClient.setAttributes(file, attrs);

        final int bufferSize = 4096;
        System.out.println("Creating buffered streams");
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(localFile), bufferSize);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new SftpFileOutputStream(file)));

        int c;            
        while ((c = in.read()) != -1) {
            out.write(c);
        }
        System.out.println("Done writing streams");
        out.close();
        in.close();
        sftpSubsystemClient.close();            
        ssh.disconnect();
    }
    System.out.println(" END ");

Что действительно интересно, так это то, что я выводю удаленные и локальные размеры пакетов просто для удовольствия, и они оба равны 65535. Похоже, что это сообщение 65580 является ошибкой в ​​SSH-сервере или инструментах SSH.

0 голосов
/ 27 октября 2009

Вы не можете изменить BLOCKSIZE. Есть несколько мест, где упоминается размер блока. Все они либо используют фиксированное значение для некоторого буфера чтения или записи, либо вызывают getBlockSize() для объекта Cipher, который является частью криптосистемы JVM.

Я не могу воспроизвести ошибку, которую вы видите. СИ попробовал с несколькими файлами разного размера, включая один из указанных вами размеров. Нечто подобное очень чувствительно к настройкам клиента и сервера.

Мой инстинкт инстинкта состоит в том, что в библиотеке j2ssh есть ошибка, связанная с размерами блоков шифра, которая создает блок больше допустимого, если где-то не учитывается заголовок пакета. Я предлагаю поэкспериментировать с настройками, чтобы посмотреть, сможете ли вы заставить клиента использовать другой шифр. Также может быть полезно загрузить исходный код j2ssh и попытаться отладить проблему напрямую. Определите, происходит ли ошибка в первом, последнем или некотором среднем пакете.

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