首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java SSH工具: SftpClient错误:远程计算机已断开连接:协议错误:数据包太长: 65580

Java SSH工具: SftpClient错误:远程计算机已断开连接:协议错误:数据包太长: 65580
EN

Stack Overflow用户
提问于 2009-10-27 05:46:35
回答 2查看 6.2K关注 0票数 1

当我尝试执行以下命令时,收到"INFO: The remote computer disconnected: Protocol error: packet too long: 65580“错误:

代码语言:javascript
复制
sUpload("server.host.com", "username", "/home/localuser/.ssh/id_rsa", "filename", "");

文件不会传输到SFTP服务器(仅在另一端创建零字节)。当通过Unix shell手动执行SFTPing时,一切都运行正常。我在网上读到SftpClient中的BLOCK_SIZE可能有问题,但首先我找不到一个设置方法来改变大小,其次,似乎默认值是65535,这完全不能解释错误消息中的65580值。

有什么想法吗?

我有以下使用Java Ssh工具的实用方法(j2ssh-core-0.2.9.jar):

代码语言:javascript
复制
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 ");
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-10-27 08:23:35

看起来下面的代码行得通--我使用了低级的"com.sshtools.j2ssh.sftp.SftpSubsystemClient“而不是"com.sshtools.j2ssh.SftpClient”,并使用输入/输出流读写文件:

代码语言:javascript
复制
    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工具中的一个错误。

票数 1
EN

Stack Overflow用户

发布于 2009-10-27 06:27:57

您不能更改块大小。有几个地方提到了块大小。它们要么使用某个读或写缓冲区的固定值,要么调用Cipher对象上的getBlockSize(),这是JVM crypto子系统的一部分。

我不能重现你看到的错误。SI尝试了几个不同大小的文件,包括您提到的其中一个文件。像这样的东西很容易受到客户端和服务器设置的影响。

我的直觉是,j2ssh库中存在一个与密码块大小相关的bug,它通过不考虑某个地方的包头来创建比允许的块更大的块。我建议修改设置,看看是否可以强制客户端使用不同的密码。下载j2ssh源代码并尝试直接调试问题也可能很有帮助。确定错误是发生在第一个、最后一个还是某个中间数据包。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1627516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档