[
https://issues.apache.org/jira/browse/NET-406?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13028154#comment-13028154
]
Sebb commented on NET-406:
--------------------------
Have you used FTPClient.setDataTimeout() to set a data timeout?
Does that work for some cases or none?
If none, then that needs to be investigated.
Not sure it's necessary to use a List<Socket>; as far as I can tell, there can
be at most one active data socket, which could be stored in a volatile field
instead.
Also, I'm not sure that extending disconnect is the correct place to do this,
as that also terminates the control connection.
It might be better to provide a means to close the data socket directly.
> Improved disconnect handling in FtpClient: retrieveFile never returns under
> certain conditions and calling FtpClient.disconnect does not terminate the
> transfer.
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: NET-406
> URL: https://issues.apache.org/jira/browse/NET-406
> Project: Commons Net
> Issue Type: Improvement
> Components: FTP
> Affects Versions: 2.0
> Environment: Linux
> Reporter: Nils Martin Sande
> Labels: features
>
> During file download it is possible for the transfer to stop without any time
> out being triggered in FtpClient. The result is a "lost" thread (it never
> returns from retrieveFile). Calling interrupt on the missing thread does not
> do anything.
> When we encountered this error we fist tried to monitor the downloaded file
> and then call FtpClient.disconnect if the size on disk remained unchanged for
> a given period of time. This did not solve the problem since
> FtpClient.disconnect does not close the socket used by the transfer. Changing
> FtpClient so that it keeps track of active sockets and then closing all
> active sockets on FtpClient.disconnect solved the problem for us. Although
> this error is not very common, the ability to completely kill the connection
> including all transfers seems like a useful feature. I have included the
> details of the modifications we made, maybe someone will find them useful. If
> there is a better way to get around this please let me know.
> {code:title=FtpClient.java_retrieveFile|borderStyle=solid}
> //The modified retrieveFile method (__activeSockets is a synchronized
> List<Socket>)
> public boolean retrieveFile(String remote, OutputStream local)
> throws IOException {
> InputStream input;
> Socket socket;
> if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
> {
> return false;
> }
> __activeSockets.add(socket);
> try {
> input = new BufferedInputStream(socket.getInputStream(),
> getBufferSize());
> if (__fileType == ASCII_FILE_TYPE) {
> input = new FromNetASCIIInputStream(input);
> }
> // Treat everything else as binary for now
> try {
> Util.copyStream(input, local, getBufferSize(),
> CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
> false);
> } catch (IOException e) {
> try {
> socket.close();
> } catch (IOException f) {
> }
> throw e;
> }
> socket.close();
> return completePendingCommand();
> } finally {
> __activeSockets.remove(socket);
> }
> }
> //The modified disconnect method
> public void disconnect() throws IOException {
> super.disconnect();
> __initDefaults();
> IOException exception = null;
> for (Socket socket : __activeSockets) {
> try {
> socket.close();
> } catch (IOException ex) {
> exception = ex;
> }
> }
> __activeSockets.clear();
> if (exception != null) {
> throw exception;
> }
> }
> {code}
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira