Hi John, this is most likely related to https://issues.apache.org/jira/browse/NET-493 Could you try with the latest 3.3-SNAPSHOT from here: https://repository.apache.org/content/groups/snapshots/commons-net/commons-net/3.3-SNAPSHOT/
Thanks, Thomas On Tue, Mar 19, 2013 at 10:59 PM, John Deviney <[email protected]>wrote: > Why would an ftp download using the commons-net library be significantly > slower on Debian Linux 6.0 than on Windows 7? The same code runs on both > platforms. I am downloading a 300MB binary file on Windows 7 in 2.5 > seconds. The same process on Debian Linux 6.0 takes hours. Further, while > on Debian Linux I can run an interactive ftp session and the file download > takes about 2.5 seconds. The only variables I can think of between these > two scenarios is the OS platform and the version of Java on each platform. > > The file being transferred is binary, hence I am using binary transfer > mode. I am also using local passive mode on both platforms. > > Windows Environment: > ================== > Windows 7 64-bit > Java 1.6.0_41 64-bit > Commons-net 3.2 > > Linux Environment: > =============== > Debian Linux 6.0 > Java 1.6.0_31 32-bit > Commons-net 3.2 > > Any suggestions to help run down this problem are appreciated. > > John Deviney > > > Source code: > > package core.util; > > import java.io.File; > import java.io.FileNotFoundException; > import java.io.FileInputStream; > import java.io.FileOutputStream; > import java.io.IOException; > import java.io.OutputStream; > import java.io.PrintWriter; > import java.net.InetAddress; > import java.util.Properties; > import java.util.logging.Level; > import java.util.logging.Logger; > > import org.apache.commons.net.PrintCommandListener; > import org.apache.commons.net.ftp.FTP; > import org.apache.commons.net.ftp.FTPClient; > import org.apache.commons.net.ftp.FTPFile; > import org.apache.commons.net.ftp.FTPReply; > > public class FtpUtil { > > public static final int DEFAULT_PORT = 21; > > public static enum TransferMode { > Binary, > Ascii > } > > public static enum ClientMode { > Active, > Passive > } > > private static final Logger logger = > Logger.getLogger(FtpUtil.class.getName()); > > > public static void ftp(String hostname, String username, String > password, String remoteDirectory, String remoteFile, String localDirectory, > String localFile, > TransferMode transferMode, ClientMode > clientMode) throws Exception { > > int replyCode = 0; > boolean authenticated = false; > int port = DEFAULT_PORT; > String fullRemotePath = enclosePathInQuotes(remoteDirectory + > remoteFile); > String fullLocalPath = enclosePathInQuotes(localDirectory + > localFile); > FTPClient ftp = new FTPClient(); > // suppress login details > ftp.addProtocolCommandListener(new PrintCommandListener(new > PrintWriter(System.out), true)); > > // connect > try > { > ftp.connect(hostname, port); > logger.log(Level.INFO, "FTP client connected to " + username + > "@" + hostname + ":" + port); > replyCode = ftp.getReplyCode(); > if (!FTPReply.isPositiveCompletion(replyCode)) > { > ftp.disconnect(); > String msg = "FTP server refused connection. Reply code = > " + replyCode + ". Refer to commons-net docs for details."; > throw new IOException(msg); > } > } > catch (Exception e) { > logger.log(Level.SEVERE, "FTP client failed to connect to " + > username + "@" + hostname + ":" + port, e); > if (ftp.isConnected()) { > try { > ftp.disconnect(); > } > catch (IOException f) { > } > } > throw e; > } > > // authenticate > try { > authenticated = ftp.login(username, password); > if (!authenticated) > { > ftp.logout(); > String msg = "FTP authentication failed."; > throw new IOException(msg); > } > } > catch (Exception e) { > logger.log(Level.SEVERE, "FTP client failed to authenticate to > " + username + "@" + hostname + ":" + port, e); > if (ftp.isConnected()) { > try { > ftp.disconnect(); > } > catch (IOException f) { > } > } > throw e; > } > > // transfer files > try { > logger.log(Level.INFO, "FTP remote system is " + > ftp.getSystemType()); > switch (transferMode) { > case Binary: > ftp.setFileType(FTP.BINARY_FILE_TYPE); > break; > case Ascii: > ftp.setFileType(FTP.ASCII_FILE_TYPE); > break; > default: > ftp.setFileType(FTP.BINARY_FILE_TYPE); > break; > } > switch (clientMode) { > case Active: > ftp.enterLocalActiveMode(); > break; > case Passive: > ftp.enterLocalPassiveMode(); > break; > default: > ftp.enterLocalPassiveMode(); > break; > } > > debugFtpSession(ftp); > OutputStream output = null; > output = new FileOutputStream(fullLocalPath); > boolean transferSuccessful = ftp.retrieveFile(fullRemotePath, > output); > output.close(); > ftp.noop(); // check that control connection is working OK > ftp.logout(); > if (!transferSuccessful) { > String msg = "FTP file transfer failed."; > throw new IOException(msg); > } > else { > logger.log(Level.INFO, "FTP file transfer successful from > " + fullRemotePath + " to " + fullLocalPath); > } > } > catch (Exception e) { > logger.log(Level.SEVERE, "FTP client failed to transfer from " > + fullRemotePath + " to " + fullLocalPath, e); > throw e; > } > finally { > if (ftp.isConnected()) { > try { > ftp.disconnect(); > } > catch (IOException f) { > } > } > } > } > > private static void debugFtpSession(FTPClient ftp) throws Exception { > int bufferSize = ftp.getBufferSize(); > int connectTimeout = ftp.getConnectTimeout(); > int defaultPort = ftp.getDefaultPort(); > int defaultTimeout = ftp.getDefaultTimeout(); > int soLinger = ftp.getSoLinger(); > int soTimeout = ftp.getSoTimeout(); > int dataConnectionMode = ftp.getDataConnectionMode(); > long controlKeepAliveTimeout = ftp.getControlKeepAliveTimeout(); > int controlKeepAliveReplyTimeout = > ftp.getControlKeepAliveReplyTimeout(); > InetAddress remoteAddress = ftp.getRemoteAddress(); > int remotePort = ftp.getRemotePort(); > String passiveHost = ftp.getPassiveHost(); > InetAddress localAddress = ftp.getLocalAddress(); > int localPort = ftp.getLocalPort(); > InetAddress passiveLocalIPAddress = ftp.getPassiveLocalIPAddress(); > int passivePort = ftp.getPassivePort(); > long restartOffset = ftp.getRestartOffset(); > String systemType = ftp.getSystemType(); > String status = ftp.getStatus(); > StringBuilder sb = new StringBuilder("Ftp session info:\n"); > sb.append("\nbufferSize: "); > sb.append(bufferSize); > sb.append("\nconnectTimeout: "); > sb.append(connectTimeout); > sb.append("\ndefaultPort: "); > sb.append(defaultPort); > sb.append("\ndefaultTimeout: "); > sb.append(defaultTimeout); > sb.append("\nsoLinger: "); > sb.append(soLinger); > sb.append("\nsoTimeout: "); > sb.append(soTimeout); > sb.append("\ndataConnectionMode: "); > sb.append(dataConnectionMode); > sb.append("\ncontrolKeepAliveTimeout: "); > sb.append(controlKeepAliveTimeout); > sb.append("\ncontrolKeepAliveReplyTimeout: "); > sb.append(controlKeepAliveReplyTimeout); > sb.append("\nremoteAddress: "); > sb.append(remoteAddress); > sb.append("\nremotePort: "); > sb.append(remotePort); > sb.append("\npassiveHost: "); > sb.append(passiveHost); > sb.append("\nlocalAddress: "); > sb.append(localAddress); > sb.append("\nlocalPort: "); > sb.append(localPort); > sb.append("\npassiveLocalIPAddress: "); > sb.append(passiveLocalIPAddress); > sb.append("\npassivePort: "); > sb.append(passivePort); > sb.append("\nrestartOffset: "); > sb.append(restartOffset); > sb.append("\nsystemType: "); > sb.append(systemType); > sb.append("\nstatus: "); > sb.append(status); > System.out.println(sb.toString()); > } > > private static String enclosePathInQuotes(String path) { > String returnString = null; > if ((path.contains(SPACE)) && !(path.startsWith(QUOTE) && > path.endsWith(QUOTE))) { > returnString = QUOTE + path + QUOTE; > } > else { > returnString = path; > } > return returnString; > } > > } >
