首页 > 解决方案 > FTPSClient仅在上传diminute文件时成功

问题描述

在将文件上传到 FTPS 服务器时,我遇到了一个严重(而且很奇怪)的问题。

我必须上传 JSON 文件,其中一些非常小(小于 5kB)。这些文件没有问题,我可以成功上传。

但是当上传“更大”的文件(不是很大,超过 30kb)时,它会显示这个错误:

java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(Unknown Source)
    at java.net.SocketOutputStream.write(Unknown Source)
    at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
    at java.io.BufferedOutputStream.flush(Unknown Source)
    at java.io.FilterOutputStream.flush(Unknown Source)
    at java.io.FilterOutputStream.close(Unknown Source)
    at org.apache.commons.net.ftp.FTPClient._storeFile(FTPClient.java:688)
    at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:639)
    at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:2030)
    at com.spsa.integracion.gastosingresos.business.impl.GastosIngresosIFImpl.envioArchivoAFTPS(GastosIngresosIFImpl.java:206)
    at com.spsa.integracion.gastosingresos.business.impl.GastosIngresosIFImpl.ejecutar(GastosIngresosIFImpl.java:90)
    at com.spsa.integracion.gastosingresos.GastosIngresosApplication.run(GastosIngresosApplication.java:27)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)
    at com.spsa.integracion.gastosingresos.GastosIngresosApplication.main(GastosIngresosApplication.java:20)
    Suppressed: java.net.SocketException: Software caused connection abort: socket write error
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(Unknown Source)
        at java.net.SocketOutputStream.write(Unknown Source)
        at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
        at java.io.BufferedOutputStream.flush(Unknown Source)
        at java.io.FilterOutputStream.close(Unknown Source)
        ... 11 more

这是我的上传代码

boolean binaryTransfer = false, success = false;

        FTPSClient ftps;

        fileName = "A134_GASTOS_M_20181024_184808.JSON";

        int port = Integer.parseInt(applicationProperties.getFtpsPort());
        String server = applicationProperties.getFtpsHost();
        String username = applicationProperties.getFtpsUsername();
        String password = applicationProperties.getFtpsPassword();
        String remote = "\\" + applicationProperties.getFolder() + "\\" + fileName;
        String local = "\\" + fileName;
        String errorMessage = "";

        ftps = new FTPSClient(true);

        ftps.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));

        try {
            int reply;

            ftps.connect(server, port);
            System.out.println("Conectado a " + server + ".");


            reply = ftps.getReplyCode();

            if (!FTPReply.isPositiveCompletion(reply)) {
                ftps.disconnect();
                System.err.println("El servidor FTP rechazo la conexion");
                System.exit(1);
            }
        } catch (IOException e) {
            if (ftps.isConnected()) {
                try {
                    ftps.disconnect();
                } catch (IOException f) {

                }
            }
            System.err.println("No se pudo conectar al servidor");
            e.printStackTrace();
            errorMessage = "No se pudo conectar al servidor";
            System.exit(1);
        }

        try {
            ftps.setBufferSize(1000);

            if (!ftps.login(username, password)) {
                ftps.logout();
            }

            System.out.println("Remote system is " + ftps.getSystemName());

            if (binaryTransfer)
                ftps.setFileType(FTP.BINARY_FILE_TYPE);

            // Use passive mode as default because most of us are
            // behind firewalls these days.
            ftps.enterLocalPassiveMode();

            InputStream input;
            input = new FileInputStream(local);

            ftps.storeFile(remote, input);
            input.close();
            ftps.logout();
            success = true;

        } catch (FTPConnectionClosedException e) {
            System.err.println("Conexion FTP cerrada");         
            errorMessage = "Conexion FTP cerrada";
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            errorMessage = "Conexion FTP cerrada";
        } finally {
            if (ftps.isConnected()) {
                try {
                    ftps.disconnect();
                } catch (IOException f) {
                    // do nothing
                }
            }
        }       

我已经尝试过使用 outpustream 并且遇到了同样的错误。还尝试使用 WinSCP 手动上传并且它有效,所以这不是权限问题。

标签: javafile-uploadftpsftp-server

解决方案


我设法解决了这个问题。发生的事情是 FTPS 服务器使用 SSL v3 协议进行连接,并且由于一些安全漏洞,Java 不推荐使用该协议。

最好的解决方案是更改 FTP 服务器的协议


推荐阅读