/// <summary> /// Asynchronous File Exchange Protocol (FXP) allows server-to-server transfer which can greatly speed up file /// transfers. /// </summary> /// <param name="fileName">The name of the file to transfer.</param> /// <param name="destination">The destination FTP server which must be supplied as an open and connected FtpClient object.</param> /// <remarks> /// Both servers must support and have FXP enabled before you can transfer files between two remote servers using FXP. /// One FTP server must support PASV mode and the other server must allow PORT commands from a foreign address. /// Finally, firewall settings may interfer with the ability of one server to access the other server. /// Starksoft FtpClient will coordinate the FTP negoitaion and necessary PORT and PASV transfer commands. /// </remarks> /// <seealso cref="FxpCopyAsyncCompleted" /> /// <seealso cref="FxpTransferTimeout" /> /// <seealso cref="FxpCopy" /> /// <seealso cref="nUpdate.Administration.Core.Ftp.FtpBase.CancelAsync" /> public void FxpCopyAsync(string fileName, FtpClient destination) { if (AsyncWorker != null && AsyncWorker.IsBusy) throw new InvalidOperationException( "The FtpClient object is already busy executing another asynchronous operation. You can only execute one asychronous method at a time."); CreateAsyncWorker(); if (AsyncWorker == null) throw new ArgumentException("AsyncWorker"); AsyncWorker.WorkerSupportsCancellation = true; AsyncWorker.DoWork += FxpCopyAsync_DoWork; AsyncWorker.RunWorkerCompleted += FxpCopyAsync_RunWorkerCompleted; var args = new Object[2]; args[0] = fileName; args[1] = destination; AsyncWorker.RunWorkerAsync(args); }
/// <summary> /// File Exchange Protocol (FXP) allows server-to-server transfer which can greatly speed up file transfers. /// </summary> /// <param name="fileName">The name of the file to transfer.</param> /// <param name="destination">The destination FTP server which must be supplied as an open and connected FtpClient object.</param> /// <remarks> /// Both servers must support and have FXP enabled before you can transfer files between two remote servers using FXP. /// One FTP server must support PASV mode and the other server must allow PORT commands from a foreign address. /// Finally, firewall settings may interfer with the ability of one server to access the other server. /// Starksoft FtpClient will coordinate the FTP negoitaion and necessary PORT and PASV transfer commands. /// </remarks> /// <seealso cref="FxpTransferTimeout" /> /// <seealso cref="FxpCopyAsync" /> public void FxpCopy(string fileName, FtpClient destination) { if (IsConnected == false) throw new FtpException( "The connection must be open before a transfer between servers can be intitiated."); if (destination == null) throw new ArgumentNullException("destination"); if (destination.IsConnected == false) throw new FtpException( "The destination object must be open and connected before a transfer between servers can be intitiated."); if (fileName == null) throw new ArgumentNullException("fileName"); if (fileName.Length == 0) throw new ArgumentException("must have a value", "fileName"); // send command to destination FTP server to get passive port to be used from the source FTP server try { destination.SendRequest(new FtpRequest(FtpCmd.Pasv)); } catch (FtpException fex) { throw new FtpException( String.Format( "An error occurred when trying to set up the passive connection on '{1}' for a destination to destination copy between '{0}' and '{1}'.", Host, destination.Host), fex); } // get the begin and end positions to extract data from the response string int startIdx = destination.LastResponse.Text.IndexOf("(", StringComparison.Ordinal) + 1; int endIdx = destination.LastResponse.Text.IndexOf(")", StringComparison.Ordinal); string dataPortInfo = destination.LastResponse.Text.Substring(startIdx, endIdx - startIdx); // send a command to the source server instructing it to connect to // the local ip address and port that the destination server will be bound to try { SendRequest(new FtpRequest(FtpCmd.Port, dataPortInfo)); } catch (FtpException fex) { throw new FtpException( String.Format("Command instructing '{0}' to open connection failed.", Host), fex); } // send command to tell the source server to retrieve the file from the destination server try { SendRequest(new FtpRequest(FtpCmd.Retr, fileName)); } catch (FtpException fex) { throw new FtpException( String.Format("An error occurred transfering on a server to server copy between '{0}' and '{1}'.", Host, destination.Host), fex); } // send command to tell the destination to store the file try { destination.SendRequest(new FtpRequest(FtpCmd.Stor, fileName)); } catch (FtpException fex) { throw new FtpException( String.Format("An error occurred transfering on a server to server copy between '{0}' and '{1}'.", Host, destination.Host), fex); } // wait until we get a file completed response back from the destination server and the source server destination.WaitForHappyCodes(FxpTransferTimeout, FtpResponseCode.RequestedFileActionOkayAndCompleted, FtpResponseCode.ClosingDataConnection); WaitForHappyCodes(FxpTransferTimeout, FtpResponseCode.RequestedFileActionOkayAndCompleted, FtpResponseCode.ClosingDataConnection); }