예제 #1
0
        /// <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 FtpsClient 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 FtpsClient will coordinate the FTP negoitaion and necessary PORT and PASV transfer commands.
        /// </remarks>
        /// <seealso cref="FxpTransferTimeout"/>
        /// <seealso cref="FxpCopyAsync"/> 
        public void FxpCopy(string fileName, FtpsClient destination)
        {
            if (this.IsConnected == false)
                throw new FtpsException("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 FtpsException("The destination object must be open and connected before a transfer between servers can be intitiated.");
            if (String.IsNullOrEmpty(fileName))
                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 FtpsRequest(base.Encoding, FtpsCmd.Pasv));
            }
            catch (FtpsException fex)
            {
                throw new FtpsException(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}'.", this.Host, destination.Host), base.LastResponse, fex);
            }

            //  get the begin and end positions to extract data from the response string
            int startIdx = destination.LastResponse.Text.IndexOf("(") + 1;
            int endIdx = destination.LastResponse.Text.IndexOf(")");
            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
            {
                this.SendRequest(new FtpsRequest(base.Encoding, FtpsCmd.Port, dataPortInfo));
            }
            catch (FtpsException fex)
            {
                throw new FtpsException(String.Format("Command instructing '{0}' to open connection failed.", this.Host), base.LastResponse, fex);
            }

            // send command to tell the source server to retrieve the file from the destination server
            try
            {
                this.SendRequest(new FtpsRequest(base.Encoding, FtpsCmd.Retr, fileName));
            }
            catch (FtpsException fex)
            {
                throw new FtpsException(String.Format("An error occurred transfering on a server to server copy between '{0}' and '{1}'.", this.Host, destination.Host), base.LastResponse, fex);
            }

            // send command to tell the destination to store the file
            try
            {
                destination.SendRequest(new FtpsRequest(base.Encoding, FtpsCmd.Stor, fileName));
            }
            catch (FtpsException fex)
            {
                throw new FtpsException(String.Format("An error occurred transfering on a server to server copy between '{0}' and '{1}'.", this.Host, destination.Host), base.LastResponse, fex);
            }

            // wait until we get a file completed response back from the destination server and the source server
            destination.WaitForHappyCodes(this.FxpTransferTimeout, FtpsResponseCode.RequestedFileActionOkayAndCompleted, FtpsResponseCode.ClosingDataConnection);
            this.WaitForHappyCodes(this.FxpTransferTimeout, FtpsResponseCode.RequestedFileActionOkayAndCompleted, FtpsResponseCode.ClosingDataConnection);
        }