После включения безопасности в сеансе FTP появляется синтаксическая ошибка 500, команда не распознана

Я использую этот код для подключения моего сервера и загрузки файлов. Работает нормально.

public void downloadFile(object args)
{
    writeStream = null;
    response = null;
    reader = null;
    int dataLength = 0;

    try
    {
        Array argArray = new object[3];
        argArray = (Array)args;
        ProgressBar progressBar1 = (ProgressBar)argArray.GetValue(0);
        Label lbProgress = (Label)argArray.GetValue(1);

        FTPInfo ftpInfo = (FTPInfo)argArray.GetValue(2);
        string ipAddress = ftpInfo.IpAddress;

        string path = ftpInfo.Path;
        string fileName = ftpInfo.FileName;

        path = Regex.Replace(path, "_.", "_e");
        fileName = Regex.Replace(fileName, "_.", "_e");

        string uri = null;
        if (path.Equals(""))
        {
            uri = ipAddress + fileName;
        }
        else
        {
            uri = ipAddress + path + "/" + fileName;
        }
        string[] temp = ipAddress.Split('/');
        string ip = "mchmultimedia.com";
        string userName = ftpInfo.UserName;
        string password = ftpInfo.Password;
        downloadedData = new byte[0];
        ftp = new FTPClass(path);
        ftp.FtpServer = ip;
        ftp.FtpUsername = userName;
        ftp.FtpPassword = password;
        ftp.FtpLogin();
        dataLength = (int)ftp.GetFileSize(fileName);
        Logger.LogDebugMessage("DataLength :" + dataLength.ToString());
        ftp.CloseConnection();
        FtpWebRequest request = FtpWebRequest.Create(uri) as FtpWebRequest;
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.Credentials = new NetworkCredential(userName, password);
        request.UsePassive = true;
        request.UseBinary = true;
        request.KeepAlive = false;

        //Set up progress bar
        UpdateProgressBarValue(progressBar1, 0);
        SetProgressBarMaxValue(progressBar1, dataLength);

        response = request.GetResponse() as FtpWebResponse;
        reader = response.GetResponseStream();

        if (!Directory.Exists(GlobalClass.ZIPPED_FOLDER))
            Directory.CreateDirectory(GlobalClass.ZIPPED_FOLDER);
        writeStream = new FileStream(GlobalClass.ZIPPED_FOLDER + "\\" + fileName, FileMode.Create);
        int Length = 2048;
        Byte[] buffer = new Byte[Length];
        int bytesRead = 0;
        Logger.LogDebugMessage("Before while :" + dataLength.ToString());
        while (true)
        {
            Application.DoEvents(); 

            bytesRead = reader.Read(buffer, 0, buffer.Length);
            if (bytesRead == 0)
            {
                try
                {
                    try
                    {
                        reader.Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.LogErrorMessage("reader close if bytesRead ==00", ex);

                    }

                    try
                    {
                        response.Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.LogErrorMessage("response close if  bytesRead ==00", ex);
                    }

                    try
                    {
                        writeStream.Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.LogErrorMessage("writeStream close if  bytesRead ==00", ex);
                    }

                }
                catch (Exception ex)
                {

                }
                UpdateProgressBarValue(progressBar1, progressBar1.Maximum);
                Application.DoEvents();
                break;
            }
            else
            {
                writeStream.Write(buffer, 0, bytesRead);

                if (progressBar1.Value + bytesRead <= progressBar1.Maximum)
                {
                    totalBytesRead = progressBar1.Value + bytesRead;
                    int percentage = (int)((double)totalBytesRead / dataLength * 100);
                    UpdateProgressBarValue(progressBar1, totalBytesRead);

                    SetText(lbProgress, "File download " + percentage.ToString() + " % completed");
                    if (percentage == 100)
                    {
                        if (totalBytesRead == dataLength)
                        {
                            try
                            {
                                try
                                {
                                    reader.Close();
                                }
                                catch (Exception ex)
                                {
                                    Logger.LogErrorMessage("reader close if percentage==100", ex);
                                }

                                try
                                {
                                    response.Close();
                                }
                                catch (Exception ex)
                                {
                                    Logger.LogErrorMessage("response close if percentage==100", ex);
                                }

                                try
                                {
                                    writeStream.Close();
                                }
                                catch (Exception ex)
                                {
                                    Logger.LogErrorMessage("writeStream close if percentage==100", ex);
                                }

                            }
                            catch (Exception ex)
                            {

                            }
                            SetText(lbProgress, "File download successfully completed,Please wait...");
                            unzipFile(fileName);
                        }

                    }

                    RefreshProgressBar(progressBar1);
                    Application.DoEvents();
                }

            }
        }
    }
    catch (System.Threading.ThreadAbortException ex)
    {
        if (thread != null)
        {
            thread.Abort();
        }
        Logger.LogErrorMessage("ThreadAbortException", ex);

    }
    catch (Exception ex)
    {
        Logger.LogErrorMessage("Exception there was an error connecting", ex);
        Logger.ReportBug("There was an error connecting to the FTP Server.", ex);
    }
    finally
    {
        try
        {
            try
            {
                reader.Close();
            }
            catch (Exception ex)
            {
                Logger.LogErrorMessage("read finally", ex);
            }

            try
            {
                response.Close();
            }
            catch (Exception ex)
            {
                Logger.LogErrorMessage("resonse finally", ex);
            }

            try
            {
                writeStream.Close();
            }
            catch (Exception ex)
            {
                Logger.LogErrorMessage("writeStream finally", ex);
            }
        }
        catch (Exception ex)
        {

        }
    }
}

Но клиенту нужно, чтобы это был безопасный FTP. Итак, я попробовал, установив

request.EnableSsl = true;

как указано в Различия между SFTP и FTP через SSH

И выкидывает:

Удаленный сервер возвратил ошибку: (500) Синтаксическая ошибка, команда не распознана.


person Vivekh    schedule 29.01.2015    source источник
comment
Итак, клиент требует, чтобы вы использовали Secure FTP (в соответствии с вашим текстом и ядром, которые вы используете) или SFTP (тег, который вы использовали)? Вы действительно понимали разницу, читая вопрос, на который вы указали ? Ошибка 500 означает, что сервер не понимает команду AUTH TLS, поэтому он не поддерживает FTP через TLS. Может быть, вы должны использовать SFTP? В ftpInfo.IpAddress указан порт?   -  person Martin Prikryl    schedule 29.01.2015
comment
Я немного запутался. Я использовал пакет SSH.NET Nuget, и он работал хорошо, но я только что наткнулся на эту ссылку, в которой говорится, что вы можете включить безопасность, просто включив SSl. Итак, я попробовал это.   -  person Vivekh    schedule 29.01.2015


Ответы (1)


Очевидно, что вам необходимо использовать протокол SFTP.

Класс FtpWebRequest не поддерживает протокол SFTP. Стандартные библиотеки .NET вообще не поддерживают SFTP. См. Библиотеки SFTP для .NET.

Ваш текущий код пытается подключиться к FTP-серверу по протоколу FTP через TLS. Это еще один способ защиты сеанса «передачи файлов». Но этот конкретный FTP-сервер не поддерживает его (отсюда и ошибка «500 синтаксическая ошибка, команда нераспознана»).

Поэтому вам нужно переписать свой код, чтобы использовать протокол SFTP.

К сожалению, это совершенно другой код.

person Martin Prikryl    schedule 29.01.2015
comment
Привет, я хотел бы спросить, есть ли какое-либо влияние на время, затрачиваемое на загрузку файла с обычного ftp (встроенного в .NET) и с использованием SSH.NET или любых других сторонних служб SFTP - person Vivekh; 29.01.2015
comment
SFTP может быть медленнее. 1) Из-за шифрования, если у любой из сторон передачи ограничена мощность процессора. 2) Протоколы SFTP (и лежащий в основе SSH) ориентированы на пакеты. Если их реализация не идеальна (опять же с обеих сторон), пропускная способность соединения с / от сервера не может быть использована на максимум. Ни то, ни другое не является проблемой с протоколом FTP. Протокол FTP, напротив, менее эффективен, чем SFTP, при работе с большим количеством небольших файлов. - person Martin Prikryl; 29.01.2015