【问题标题】:Apache Commons FTPClient.storeFile() error Caused by: java.net.SocketException: Connection resetApache Commons FTPClient.storeFile() 错误原因:java.net.SocketException:连接重置
【发布时间】:2016-07-01 16:44:14
【问题描述】:

我进行了新的编辑 (2),问题似乎是图像实际上正在被存储,但有时需要一段时间来存储它们(很多分钟,通常需要大约一秒钟)。我很好奇它是否可能是我的服务器?我发现很奇怪,当我运行它时我没有问题(几个月前我一直在从事另一个项目),所以我很好奇为什么现在有问题,所以服务器端可能有意义,但这是一个大问题现在如果是这样...


我有一个连接到我的服务器并将文件/图像保存到服务器的应用程序。我最初将文件保存在我的计算机上,然后上传这些文件;但是,由于我不想保存文件,所以我选择了使用 ByteArrayOutputStream。

由于某种原因,在我上传文件的过程中,我的 JavaFX 应用程序会随机挂起。

当单击 x 时,它会询问我是否要尝试“恢复”应用程序,当我这样做时,它会抛出一个错误的堆栈跟踪。

原因:java.net.SocketException:连接重置

我在这里和 Google 上搜索了多个帖子,但没有任何帮助。

到目前为止,我已经尝试过了。

  1. "ftp.enterLocalPassiveMode(已启用)。
  2. 更改超时,例如连接和数据。
  3. Java 7 中的一些错误,您必须运行命令行脚本才能修复(我正在运行 Java 8 Update 71)。
  4. 一些 exec 命令似乎只对 FTPSClient 有用,对 FTPClient 没有用

还有一些东西告诉我增加缓冲区大小,用户做了“setBufferSize(1024*1024),而默认值,对我来说,是 0... 仍然没有'改变任何东西。

到目前为止,没有任何效果,奇怪的是它会上传随机数量的图像,然后挂起。我一直注意到,我尝试上传这些图片的次数越多,它们似乎上传的越多,在挂起之前,但曾经有一次它挂在第一张图片上,所以我不知道......

我运行了 Netbeans Profiler,但我不确定“线程转储”中是否显示了任何不正常的内容,但如果需要,我可以发布。


我的代码如果重要的话。

   for(Data f: plan.getData())
        {

                    BufferedImage b  = image;  //reduced code here
                    os =  new ByteArrayOutputStream();

                    ImageIO.write(b, "PNG", os);
                    is = new ByteArrayInputStream(os.toByteArray());


                    ftp.storeFile(f.getName(), is); // Application hangs/ Connection Resets here after x amount of stores.

       }

FTP 连接:

    {
         ftp.setDefaultTimeout(100000000);
      ftp.connect();
      ftp.login();

      // use local passive mode to pass firewall
      ftp.enterLocalPassiveMode();

        //System.out.print(ftp.getReplyString()); 


        //keeps connection alive (doesn't really work)

//Tried to set as many timeouts as I could as I read some of these could be the issue too...
        ftp.setKeepAlive(true);
         ftp.setControlKeepAliveTimeout(100000);
         ftp.setControlKeepAliveReplyTimeout(10000);
         ftp.setConnectTimeout(100000);
         ftp.setDataTimeout(300);
         ftp.setSoTimeout(100000);



        //sets buffer size to allow more files to be transferred.
        System.out.println("Buffer Size:" + ftp.getBufferSize());
        ftp.setBufferSize(1024 * 1024);
        System.out.println("Buffer Size:" + ftp.getBufferSize()); 


    }

另外,对于它的价值,在关闭程序后,我在控制台中用红色字母显示该行

Java 结果:-805306369

我在 Google 上找不到这个结果编号,也不知道我们是否在特定的地方寻找结果。

如果有人有任何建议,我将不胜感激......

这真的让我很困扰,特别是因为我之前存储带有图像的文件完全没有问题......

感谢您的帮助!


堆栈跟踪:

    SEVERE: null
java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:209)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.read(BufferedReader.java:182)
    at org.apache.commons.net.io.CRLFLineReader.readLine(CRLFLineReader.java:58)
    at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:314)
    at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:294)
    at org.apache.commons.net.ftp.FTP.getReply(FTP.java:694)
    at org.apache.commons.net.ftp.FTPClient.completePendingCommand(FTPClient.java:1830)
    at org.apache.commons.net.ftp.FTPClient._storeFile(FTPClient.java:689)
    at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:639)
    at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:1996)

编辑:我尝试更改为只读取文件,这是我第一次做的,我得到了同样的错误。

我稍微修改了代码,并把它放在不同的地方,但一切本质上都是一样的......

唯一这两个版本之间的变化,除了很多时间,是我换了电脑……这是一个 JavaFX 应用程序,所以我不认为我对 Tomcat 所做的更改在我的旧电脑上会很重要,但我要看看我的旧电脑是否会导致这个问题....


EDIT2:我检查了旧计算机,它使用的是相同版本的 Apache-Commons-Net (3.4),但我无法在以前的状态下运行应用程序,所以我会看看是否可以修复它这样做,或尝试其他选项。

为了它的价值,我决定不点击“x”退出,或者根本不触摸应用程序,而只是观察输出。

通常,它会将一些文件存储到服务器,然后崩溃,但后来我意识到我的应用程序一直“挂起”,如果我真的等待一段时间,它会存储其他图像/文件。

所以现在我很困惑这里的问题到底是什么。是我的服务器有问题,还是我的问题?我认为这更多是服务器的错,如果图像/内容有时被快速保存(当我做秒表时每张图像大约 1 秒),但其他时候需要几分钟或更长时间。我将尝试获取完整的 StopWatch 堆栈跟踪以查看发生了什么。

似乎执行“thread.sleep(x)”或 ftp 断开连接,然后连接有时有助于更轻松地移动文件存储。不确定这是否只是运气,或者这是否在某种程度上有所帮助....

【问题讨论】:

    标签: java sockets ftp connection apache-commons-net


    【解决方案1】:

    概率.....

    1) 有时您会在 ftp.config 文件中更改监听路径,因为您会遇到连接重置问题。

    2) 在你尝试 Java API 之前,你可以手动执行并查看日志,你就会有一个清晰的想法。

    【讨论】:

      【解决方案2】:

      这个答案可能会帮助一些与我有类似程序的人。

      基本上我必须在我的防病毒应用程序中允许正确的权限才能允许存储文件。这很奇怪,因为正如我之前所说,这在我的旧电脑上工作,旧电脑有同样的保护......


      我尝试了什么:

      1. 我尝试更改代码中的设置,但没有任何效果,有些会很快导致超时。 这导致我尝试使用 FTPClient 和其他服务器,以为这是我的服务器

      2. 我尝试连接到另一台计算机上的 2 个不同的服务器,但那里也出现了一些问题。 这导致我尝试通过我的代码连接到第二台服务器

      3. 在我的代码中的第二台服务器出现问题后,我意识到这一定是我的问题(奇怪的是 server1 会挂起 15 分钟,每次挂起,但 server2 会挂起 10 分钟每次.... 这让我尝试了我的防病毒软件

      4. 我尝试暂停对我的 AV 的保护,并完全关闭 AV 程序,这都给了我不同的错误。 这导致我寻找 Windows 防火墙以查看那里是否存在问题

      5. Windows 防火墙已打开,通过将其关闭并再次尝试 4 中的步骤,我正要让它工作。


      我不确定是否需要启动 Windows 防火墙,因为我的 AV 安装了另一个防火墙,而且我发现 Windows 防火墙导致问题很奇怪,因为默认情况下允许所有“出站”数据包.. ..

      【讨论】:

        【解决方案3】:

        Apache Commons Net 3.4 ApisetControlKeepAliveTimeout方法中描述如下:

        设置发送控制连接keepalive之间的等待时间 处理文件上传或下载时的消息。

        因此,如果您想保持连接处于活动状态,您应该尝试减少控制消息之间的等待时间。

        在 API 定义中再次声明,此功能仅在以下方法中启用:

        • retrieveFile(String, OutputStream)
        • appendFile(String, InputStream)
        • storeFile(String, InputStream)
        • storeUniqueFile(InputStream)
        • storeUniqueFileStream(String)

        而不是在

        retrieveFileStream(String) , storeFileStream(String) 和其他 xxxFileStream 方法。

        最后提示:上传字节图像文件还需要设置文件类型和传输方式如下:

        ftp.setFileType(FTP.BINARY_FILE_TYPE, FTP.BINARY_FILE_TYPE);
        ftp.setFileTransferMode(FTP.BINARY_FILE_TYPE);
        

        希望这会有所帮助。

        【讨论】:

        • 感谢您的信息,没有意识到其中一些是不同的,即秒与毫秒,此方法用于发送保持活动消息与超时时间。这并没有做任何特别的事情,我将其设置为 10。我确实尝试过 Thread.Sleep();看看是不是我上传文件的速度太快了,即使我从中得到了更多的文件,最后它仍然崩溃了。我确实找到了 if(ftp.completePendingCommand());这可能有效。
        【解决方案4】:

        要尝试的事情:

        a.) 每次上传后关闭 ftp 客户端,然后在开始下一次上传之前重新打开 ftp 客户端。这可以避免任何类型的服务器超时或网络超时。我知道这是低效的,但服务器和网络可以内置超时。

        b.) 尝试使用缓冲输出流到服务器(如果 Data 或 Apache FTPClient 尚未这样做)。缓冲的输入流很好,但是尝试“写入”到服务器时会发生网络延迟。

        【讨论】:

        • A.我会看看每次重新连接是否会在我第二次尝试获取文件列表时遇到类似的问题。 IT 遇到了一些奇怪的连接关闭错误,并给了我一个 421 的回复代码。这很奇怪,因为我的整个应用程序基本上都是通过 FTP 运行的,而且我一直在更改目录和各种废话,但我遇到了这两个奇怪的问题...至于“超时”,我们可以自己更改它们,但在这方面没有运气。 B. 我不确定它是如何工作的,因为 storeFiles 的参数是 String 和 InputStream。
        • 一些其他的尝试:
        • 我尝试关闭并重新打开它似乎有帮助,但同时,在尝试了很多次之后,似乎连接很慢(请参阅我的编辑),所以重新连接没有帮助。我确实尝试使用“storeFileStream”,但在第二次甚至第一次上传时我的输出流为空时遇到错误,但上传速度要快得多。我已经随机阅读了一些关于用户名/密码中特殊字符的内容,所以我将看看这是否可能是一个问题。但是,我的服务器是 ERR_CONNECTION_TIMEOUT,所以我无法在 atm 做任何事情。
        • 我感觉我的主机(Daily Razor)是造成这种情况的原因。在过去的几次尝试中,我对 FTP 会话一直重新连接有一些模糊的记忆,所以我想我会再试一次看看。 PITA,但至少如果它是我的主人,我可以(希望)相当简单地切换。
        • 在很多事情上都使用过 Apache 的 FTPClient,我发现此类问题与代码关系不大,而与网络和服务器有关。其他一些尝试:a.) 显式设置端口。虽然 ftp 应该默认为 21,sftp 应该默认为 22,但您应该根据 ftp/sftp 设置端口。 b.)仔细检查服务器的端口......即远程登录 。像“以前工作但现在不工作”和“有时工作”这样的奇怪现象可能表明服务器上的 ftp/sftp 服务正在崩溃然后重新启动。
        猜你喜欢
        • 2017-08-15
        • 2017-09-10
        • 1970-01-01
        • 1970-01-01
        • 2016-05-17
        • 1970-01-01
        • 1970-01-01
        • 2011-11-01
        • 2010-09-08
        相关资源
        最近更新 更多