You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Oscar Usifer <os...@programmer.net> on 2007/08/03 00:52:19 UTC

Re: [commons-net] How to add timeouts to FTP client connections?

Folks, Resolved using a threaded approach by wrapping the ftp ops in a
thread. If thread joins(timeout)/isAlive expires before thread dies, the
server is deemed offline. The implementation was successful in both jsp
and java app, but caused a delay in exiting the app to wait for the TCP
native socketwrite call to time out (about 15 minutes). This seemed
acceptable since it allowed all processing to finish. The correct
re-implementation would be with java.nio.*, but after looking at this, I
decided I couldn't get a firm grasp on how to do it without a long
learning delay (and life is short). -OSC

  ----- Original Message -----
  From: "Oscar Usifer"
  To: "Jakarta Commons Users List"
  Subject: Re: [commons-net] How to add timeouts to FTP client
  connections?
  Date: Tue, 24 Jul 2007 12:14:13 -0500


  Folks, Turns out that setSoTimeout is a timeout set on reading data
  from
  the socket, but not writing data which is what's required from the
  client. This behavior was reported in
  http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4031100, and seems
  to
  have some implications on this type for time out. There seems to be a
  work around via java.nio, which I will try and implement. Thanks,OSC

  ----- Original Message -----
  From: "Oscar Usifer"
  To: commons-user@jakarta.apache.org
  Subject: [commons-net] How to add timeouts to FTP client connections?
  Date: Mon, 23 Jul 2007 18:41:43 -0500


  Folks,

  I am writing an ftp client that uploads a file to more than one
  (many) ftp servers simultaneously. I want to add some fault
  tolerance so that if one server goes offline during the transfer,
  the upload is completed to the running servers. I've tried to
  capture this situation by blocking packets (via iptables) on one
  ftp server, and seeing if it triggers a timeout condition/exception
  (from setting setSoTimeout) in the ftp client, but unfortuantley
  the connection only hangs. Note I am using rwinston's
  commons-net-ftp-2.0.0-SNAPSHOT.jar. The code below is a command
  line example of the ftp client. Any suggestions?

  Thanks,
  OSC

  import java.io.OutputStream;
  import org.apache.commons.net.ftp.FTPClient;
  public class FTPServer {
  boolean online = true;
  FTPClient client = null;
  String hostname = null;
  OutputStream os = null;
  }

  import java.io.FileInputStream;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.PrintWriter;
  import java.util.Random;

  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.FTPConnectionClosedException;
  import org.apache.commons.net.ftp.FTPReply;


  public class Fdb {
  public static final String USAGE =
  "Usage: Fdb \n" +
  "\nUploads local file to remote ftp servers in binary transfer
  mode.\n";

  public static void main(String[] args) {
  String[] ftphost = { "filedb1.test", "filedb2.test"};
  FTPServer[] ftpsvr = new FTPServer[ftphost.length];
  File fl = null;
  FileInputStream is = null;

  if (args.length == 0) {
  System.out.println(USAGE);
  System.exit(-1);
  }

  try {
  fl = new File(args[0]);
  is = new FileInputStream(fl);
  } catch (Exception e) {
  System.exit(-1);
  }

  // data type initialization
  for (int i = 0; i < ftpsvr.length; ++i) {
  ftpsvr[i] = new FTPServer();
  ftpsvr[i].client = new FTPClient();
  ftpsvr[i].client.setConnectTimeout(1000); // one sec timeout
  try {
  ftpsvr[i].client.setSoTimeout(1000);
  } catch(Exception e) {}
  ftpsvr[i].client.addProtocolCommandListener(new PrintCommandListener(
  new PrintWriter(System.out)));
  ftpsvr[i].hostname = ftphost[i];
  }

  // ftp connections
  for (int i = 0; i < ftpsvr.length; i++) {
  try {
  ftpsvr[i].client.connect(ftpsvr[i].hostname);

  if
  (FTPReply.isPositiveCompletion(ftpsvr[i].client.getReplyCode())) {
  System.out.println(ftpsvr[i].hostname + " ftp connection");
  ftpsvr[i].online = true;
  System.out.println(ftpsvr[i].hostname + " marked
  server online");
  } else {
  System.out.println(ftpsvr[i].hostname + " no ftp connection");
  System.out.println(ftpsvr[i].hostname + " marked
  server offline");
  }
  } catch (Exception e) {
  ftpsvr[i].online = false;
  }
  }

  // connection negotiation
  for (int i = 0; i < ftpsvr.length; i++) {
  if (ftpsvr[i].online) {
  ftpsvr[i].client.enterLocalPassiveMode();
  try {
  ftpsvr[i].client.login("ftp", "");
  ftpsvr[i].client.setFileType(FTPClient.BINARY_FILE_TYPE);
  ftpsvr[i].client.changeWorkingDirectory("/pub/incoming");

  // added random number for testing purposes
  ftpsvr[i].os =
  ftpsvr[i].client.storeFileStream((new Random()).nextInt(1000) +
  args[0]);
  } catch (java.io.IOException e) {
  ftpsvr[i].online = false;
  }
  }
  }

  // Writing input byte streams to ftp server destinations
  byte buf[] = new byte[8192];

  int bytesRead = 0;

  try {
  bytesRead = is.read(buf);
  } catch(Exception e) {}

  System.out.println("writing data");
  while (bytesRead != -1) {
  // write data out to ftp servers
  for (int i = 0; i < ftpsvr.length; i++) {
  try {
  if (ftpsvr[i].online) {
  if
  (FTPReply.isPositivePreliminary(ftpsvr[i].client.getReplyCode())
  && ftpsvr[i].os != null) {
  System.out.print(".");
  ftpsvr[i].os.write(buf, 0, bytesRead);
  } else {
  System.out.println("non - positive reply on "
  + ftpsvr[i].hostname);
  }
  }
  } catch (Exception e1) {
  // here we're assuming any exception was generated by
  // an I/O fault related to writing to the ftp server,
  // thus the server is offline

  System.out.println("**FAULT writing to " + ftpsvr[i].hostname);
  ftpsvr[i].online = false;
  }
  }

  try {
  bytesRead = is.read(buf);
  } catch (Exception e) {}
  }

  System.out.println("done.");
  try {
  is.close();
  } catch (Exception e) {}

  for (int i = 0; i < ftpsvr.length; i++) {
  if (ftpsvr[i].online) {
  System.out.println("closing output stream " + ftpsvr[i].hostname);
  try {
  ftpsvr[i].os.close();
  ftpsvr[i].client.completePendingCommand();
  ftpsvr[i].client.logout();
  ftpsvr[i].client.disconnect();
  } catch (Exception e) {}
  }
  }
  }
  }


  --
  We've Got Your Name at http://www.mail.com!
  Get a FREE E-mail Account Today - Choose From 100+ Domains


  ---------------------------------------------------------------------
  To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
  For additional commands, e-mail: commons-user-help@jakarta.apache.org

  --
  We've Got Your Name at http://www.mail.com!
  Get a FREE E-mail Account Today - Choose From 100+ Domains

-- 
We've Got Your Name at http://www.mail.com!
Get a FREE E-mail Account Today - Choose From 100+ Domains