上传文件后ftp4j读取超时
ftp4j read timed out after upload file
我在从特定工作站上传文件(使用 ftp4j 库)期间收到奇怪的异常。
文件上传 (100%) 后,我收到读取超时异常。这是:
2015-03-20 18:14:43 INFO TranferFileFtp4j:760 - FTP Server supports resume. Trying to upload file
2015-03-20 18:14:43 INFO Ftp4jListener:38 - TRANSFER-STATUS: File transfer started
2015-03-20 18:14:43 INFO Ftp4jListener:47 - File: 152818571.zip | Bytes transfered 65536 Percentage: 0.024173772%
...
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244383744 Percentage: 99.89077%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244449280 Percentage: 99.91756%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244514816 Percentage: 99.94434%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244580352 Percentage: 99.97113%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244645888 Percentage: 99.99792%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244650979 Percentage: 100.0%
2015-03-20 18:20:18 INFO TranferFileFtp4j:803 - Failed to send File! IOException other exceptionRead timed out - null
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at sun.nio.cs.StreamDecoder.read0(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at it.sauronsoftware.ftp4j.NVTASCIIReader.readLine(NVTASCIIReader.java:105)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.read(FTPCommunicationChannel.java:142)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.readFTPReply(FTPCommunicationChannel.java:187)
at it.sauronsoftware.ftp4j.FTPClient.upload(FTPClient.java:2797)
at it.sauronsoftware.ftp4j.FTPClient.upload(FTPClient.java:2586)
at com.npap.network.TranferFileFtp4j.uploadFileFtps5(TranferFileFtp4j.java:765)
at com.npap.utils.ProcessDicomFiles.sendZippFiles(ProcessDicomFiles.java:215)
at com.npap.scheduler.MainJob.execute(MainJob.java:97)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at sun.nio.cs.StreamDecoder.read0(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at it.sauronsoftware.ftp4j.NVTASCIIReader.readLine(NVTASCIIReader.java:105)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.read(FTPCommunicationChannel.java:142)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.readFTPReply(FTPCommunicationChannel.java:187)
at it.sauronsoftware.ftp4j.FTPClient.disconnect(FTPClient.java:1133)
at com.npap.network.TranferFileFtp4j.uploadFileFtps5(TranferFileFtp4j.java:826)
at com.npap.utils.ProcessDicomFiles.sendZippFiles(ProcessDicomFiles.java:215)
at com.npap.scheduler.MainJob.execute(MainJob.java:97)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
这是代码:
ftpClient = Ftp4jUtility.ftpsConnect(SERVER_MACHINE, PORT, SERVER_USERNAME, SERVER_PASSWORD, stdId);
ftpClient.changeDirectory(config.getFtpRemoteFolderUploads());
if(ftpClient.isResumeSupported()) {
ftpClient.upload(localFile, writtenBytes, new Ftp4jListener(localFile.length(), localFile.getName()));
} else {
ftpClient.upload(localFile, new Ftp4jListener(localFile.length(), localFile.getName()));
}
completed = true;
} catch (FTPAbortedException e) {
....
break;
} catch (FTPDataTransferException ex1) {
studyDetailsDAO.updateStudyIsInProgress(stdId, false);
ex1.printStackTrace();
....
} catch (FTPException ex1) {
ex1.printStackTrace();
....
} catch (FTPIllegalReplyException ex1) {
ex1.printStackTrace();
...
} catch (IOException ex1) {
log.info("Failed to send File! IOException " + ex1.getMessage());
ex1.printStackTrace();
} catch (IllegalStateException ex1) {
...
} finally {
if(ftpClient!=null && ftpClient.isConnected()) {
try {
ftpClient.disconnect(true);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
我收到此异常:IOException - 读取超时!任何想法是什么造成的?或者如何进行调试?
奇怪的是所有 ftp 操作都正常!我也能够开始并实际上传文件,但是在 ftpClient.upload 操作结束时我收到了这个超时!
我也检查过并发现我从特定工作站遇到了这个特殊问题。我什至尝试使用 filezilla 上传文件,但我收到了类似的异常(读取超时)。所以我猜这是网络或防火墙问题...有什么想法吗?
有什么想法吗?
可能的问题
FTP 协议在客户端和服务器之间使用单独的控制和数据 TCP 连接。在文件传输期间,数据连接繁忙,但控制连接空闲。根据您的日志,传输需要 15 分钟。这意味着控制连接在那段时间是空闲的。某些防火墙或网络路由器可以在一段时间内没有任何 activity 断开连接。看起来是这样,因为 readFTPReply
尝试从控制连接读取并抛出 "Read timed out".
如何调试
你可以通过Wireshark or tcpdump在客户端进行流量转储,并尝试找出控制连接断开的原因。
如何修复
我可以看到两种解决问题的方法:
您可以通过控制连接 ping 服务器发送 NOOP
命令以在传输期间进行一些 activity 并在 firewalls/routers 中重置连接的空闲计时器。我不确定 ftp4j 是否可以做到这一点。但是你可以切换到 Apache FTPClient and use setControlKeepAliveTimeout.
你可以试试update/change firewalls/routers.
我在从特定工作站上传文件(使用 ftp4j 库)期间收到奇怪的异常。
文件上传 (100%) 后,我收到读取超时异常。这是:
2015-03-20 18:14:43 INFO TranferFileFtp4j:760 - FTP Server supports resume. Trying to upload file
2015-03-20 18:14:43 INFO Ftp4jListener:38 - TRANSFER-STATUS: File transfer started
2015-03-20 18:14:43 INFO Ftp4jListener:47 - File: 152818571.zip | Bytes transfered 65536 Percentage: 0.024173772%
...
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244383744 Percentage: 99.89077%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244449280 Percentage: 99.91756%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244514816 Percentage: 99.94434%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244580352 Percentage: 99.97113%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244645888 Percentage: 99.99792%
2015-03-20 18:20:08 INFO Ftp4jListener:47 - File: 153740599.zip | Bytes transfered 244650979 Percentage: 100.0%
2015-03-20 18:20:18 INFO TranferFileFtp4j:803 - Failed to send File! IOException other exceptionRead timed out - null
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at sun.nio.cs.StreamDecoder.read0(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at it.sauronsoftware.ftp4j.NVTASCIIReader.readLine(NVTASCIIReader.java:105)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.read(FTPCommunicationChannel.java:142)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.readFTPReply(FTPCommunicationChannel.java:187)
at it.sauronsoftware.ftp4j.FTPClient.upload(FTPClient.java:2797)
at it.sauronsoftware.ftp4j.FTPClient.upload(FTPClient.java:2586)
at com.npap.network.TranferFileFtp4j.uploadFileFtps5(TranferFileFtp4j.java:765)
at com.npap.utils.ProcessDicomFiles.sendZippFiles(ProcessDicomFiles.java:215)
at com.npap.scheduler.MainJob.execute(MainJob.java:97)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.security.ssl.InputRecord.readFully(Unknown Source)
at sun.security.ssl.InputRecord.read(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at sun.nio.cs.StreamDecoder.read0(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at it.sauronsoftware.ftp4j.NVTASCIIReader.readLine(NVTASCIIReader.java:105)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.read(FTPCommunicationChannel.java:142)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.readFTPReply(FTPCommunicationChannel.java:187)
at it.sauronsoftware.ftp4j.FTPClient.disconnect(FTPClient.java:1133)
at com.npap.network.TranferFileFtp4j.uploadFileFtps5(TranferFileFtp4j.java:826)
at com.npap.utils.ProcessDicomFiles.sendZippFiles(ProcessDicomFiles.java:215)
at com.npap.scheduler.MainJob.execute(MainJob.java:97)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
这是代码:
ftpClient = Ftp4jUtility.ftpsConnect(SERVER_MACHINE, PORT, SERVER_USERNAME, SERVER_PASSWORD, stdId);
ftpClient.changeDirectory(config.getFtpRemoteFolderUploads());
if(ftpClient.isResumeSupported()) {
ftpClient.upload(localFile, writtenBytes, new Ftp4jListener(localFile.length(), localFile.getName()));
} else {
ftpClient.upload(localFile, new Ftp4jListener(localFile.length(), localFile.getName()));
}
completed = true;
} catch (FTPAbortedException e) {
....
break;
} catch (FTPDataTransferException ex1) {
studyDetailsDAO.updateStudyIsInProgress(stdId, false);
ex1.printStackTrace();
....
} catch (FTPException ex1) {
ex1.printStackTrace();
....
} catch (FTPIllegalReplyException ex1) {
ex1.printStackTrace();
...
} catch (IOException ex1) {
log.info("Failed to send File! IOException " + ex1.getMessage());
ex1.printStackTrace();
} catch (IllegalStateException ex1) {
...
} finally {
if(ftpClient!=null && ftpClient.isConnected()) {
try {
ftpClient.disconnect(true);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
我收到此异常:IOException - 读取超时!任何想法是什么造成的?或者如何进行调试?
奇怪的是所有 ftp 操作都正常!我也能够开始并实际上传文件,但是在 ftpClient.upload 操作结束时我收到了这个超时!
我也检查过并发现我从特定工作站遇到了这个特殊问题。我什至尝试使用 filezilla 上传文件,但我收到了类似的异常(读取超时)。所以我猜这是网络或防火墙问题...有什么想法吗?
有什么想法吗?
可能的问题
FTP 协议在客户端和服务器之间使用单独的控制和数据 TCP 连接。在文件传输期间,数据连接繁忙,但控制连接空闲。根据您的日志,传输需要 15 分钟。这意味着控制连接在那段时间是空闲的。某些防火墙或网络路由器可以在一段时间内没有任何 activity 断开连接。看起来是这样,因为 readFTPReply
尝试从控制连接读取并抛出 "Read timed out".
如何调试
你可以通过Wireshark or tcpdump在客户端进行流量转储,并尝试找出控制连接断开的原因。
如何修复
我可以看到两种解决问题的方法:
您可以通过控制连接 ping 服务器发送
NOOP
命令以在传输期间进行一些 activity 并在 firewalls/routers 中重置连接的空闲计时器。我不确定 ftp4j 是否可以做到这一点。但是你可以切换到 Apache FTPClient and use setControlKeepAliveTimeout.你可以试试update/change firewalls/routers.