FtpWebRequest - Ошибка аутентификации, поскольку удаленная сторона закрыла транспортный поток - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть код внутри httphandler, который я использую для обслуживания файлов на веб-сайте. В основном это используется в качестве динамической замены вместо прямой связи с файлом. Он принимает ID в качестве входных данных, проверяет базу данных и разрешения, а затем отвечает обратно связанным файлом. Сам файл хранится вне сайта в другом месте. Я был проинструктирован использовать ftp, чтобы вернуть файл на наш сервер. Наша серверная среда использует .net 3.5.

Код, который у меня есть, работает без ошибок, когда одновременно выполняется только одно действие ftp .

Однако, когда httphandler вызывается несколько раз одновременно (например, если 4 человека используют его один раз или один человек выполняет 4 раза одновременно), то некоторые из выполнений завершаются неудачно с ошибкой Удаленный сервер возвратил ошибку: 150 Открытие данных канал для загрузки файла с сервера XXX: аутентификация не удалась, потому что удаленная сторона закрыла транспортный поток.

Я изначально использовал сторонние библиотеки fluentFTP, когда столкнулся с этой проблемой. Я подумал, что, возможно, это была сторонняя библиотека, вызывающая проблему, поэтому при отладке я перешел просто использовать FtpWebRequest в приведенном ниже коде, но возникает та же ошибка.

Я читал возможные исправления за последние пару дней. Многие общие ответы были опробованы и не сработали: они включают в себя:

Настройка ServicePointManager.SecurityProtocol

Установка верхнего предела соединения

Настройка группы соединений для каждого выполнения.

Ни одно из этих изменений не повлияло на выполнение кода.

Краткое описание кода указано ниже

try
{
    //Hook a callback to verify the remote certificate
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(MyCertValidationCb);
    ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol = (SecurityProtocolType)48 | (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;

    FtpWebRequest reqFTP = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + hostAddress + downloadByFtpSource));
    reqFTP.Credentials = new NetworkCredential(ftpUSername, ftpPassword);
    reqFTP.EnableSsl = true;
    reqFTP.UsePassive = true;
    reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
    reqFTP.UseBinary = true;

    reqFTP.KeepAlive = false;
    reqFTP.ServicePoint.ConnectionLimit = 100;
    Random r = new Random();
    var debugTestingRandomNumber = (-1 * r.Next(1000000));
    string debugTestingGroupName = "MyGroupName" + debugTestingRandomNumber.ToString();
    reqFTP.ConnectionGroupName = debugTestingGroupName;

    using (Stream ftpStream = reqFTP.GetResponse().GetResponseStream())                           
    using (Stream fileStream = File.Create(downloadByFtpDestination))
    {

        CopyTo(ftpStream, fileStream);                    
        FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
        var debuggingTest = response.StatusCode.ToString();

        result = true;

    }
    reqFTP.ServicePoint.CloseConnectionGroup(debugTestingGroupName);               
}
catch (Exception ex)
{
    result = false;
}

отредактировано: добавить в строку reqFTP.UseBinary = true;

...