commons.net FTPSClient.storeFile在与服务器的连接丢失时不会抛出IOException。



背景:

我试图添加一些级别的容错性的应用程序,使用Apache Commons.net FTPSClient传输文件。如果客户机和服务器之间的连接失败,我想捕获生成的异常/返回代码,记录详细信息,并尝试重新连接/重试传输。

哪些是有效的方式:

retrieveFile()方法。如果连接失败,(即我禁用服务器的公共接口),在我指定的超时时间之后,我将收到由SocketTimeoutException引起的CopyStreamException。

什么不能用:

storeFile()方法。如果我通过storeFile()启动传输并禁用服务器的公共接口,storeFile()方法会无限期阻塞/挂起,而不会抛出任何异常。

这是一个简单的应用程序,当连接被终止时挂起:

public class SmallTest {
private static Logger log = Logger.getLogger(SmallTest.class);
/**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {
    FTPSClient client = new FTPSClient(true);
    FTPSCredentials creds = new FTPSCredentials("host", "usr", "pass", 
            "/keystore/ftpclient.jks", "pass", 
            "/keystore/rootca.jks");
    String file = "/file/jdk-7u21-linux-x64.rpm";
    String destinationFile = "/jdk-7u21-linux-x64.rpm";
    client.setTrustManager(TrustManagerUtils.getValidateServerCertificateTrustManager());
    client.setKeyManager(creds.getKeystoreManager());
    client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
    client.setCopyStreamListener(createListener());
    client.setConnectTimeout(5000);
    client.setDefaultTimeout(5000);
    client.connect(creds.getHost(), 990);   
    client.setSoTimeout(5000);
    client.setDataTimeout(5000);
    if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
        client.disconnect();
        log.error("ERROR: " + creds.getHost() + " refused the connection");
    } else {
        if (client.login(creds.getUser(), creds.getPass())) {
            log.debug("Logged in as " + creds.getUser());
            client.enterLocalPassiveMode();     
            client.setFileTransferMode(FTP.BLOCK_TRANSFER_MODE);
            client.setFileType(FTP.BINARY_FILE_TYPE);
            InputStream inputStream = new FileInputStream(file);
            log.debug("Invoking storeFile()");
            if (!client.storeFile(destinationFile, inputStream)) {
                log.error("ERROR: Failed to store " + file
                        + " on remote host. Last reply code: "
                        + client.getReplyCode());
            } else {
                log.debug("Stored the file...");
            }
            inputStream.close();
            client.logout();
            client.disconnect();
        } else {
            log.error("Could not log into " + creds.getHost());
        }
    }
}
private static CopyStreamListener createListener(){
    return new CopyStreamListener(){
        private long megsTotal = 0;
        @Override
        public void bytesTransferred(CopyStreamEvent event) {
            bytesTransferred(event.getTotalBytesTransferred(), event.getBytesTransferred(), event.getStreamSize());
        }
        @Override
        public void bytesTransferred(long totalBytesTransferred,
                int bytesTransferred, long streamSize) {
            long megs = totalBytesTransferred / 1000000;
            for (long l = megsTotal; l < megs; l++) {
                System.out.print("#");
            }
            megsTotal = megs;
        }
    };
}

是否有办法使连接实际上超时?

软件版本:

成为Commons.net v3.3Java 7CentOS 6.3

提前感谢,

我遇到了同样的问题,我认为当我拔掉笔记本电脑上的以太网电缆时,我能够得到一些似乎与期望的超时行为一起工作的东西。

我使用'storeFileStream'而不是'storeFile',然后使用'completePendingCommand'完成传输。您可以查看Apache commons文档中的'completePendingCommand',以查看此类传输的示例。它花了大约15分钟为我暂停。还有一件事:前面提到的文档包括调用'isPositiveIntermediate'来检查错误,但这不起作用。我用"isPositivePreliminary"代替了它,现在它似乎起作用了。我不确定这是否正确,但这是目前为止我发现的最好的。

相关内容

  • 没有找到相关文章