У меня есть код внутри 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;