При попытке загрузить файл с удаленного FTP-сервера выдается следующее исключение:
The underlying connection was closed: The server committed a protocol violation.
Файл ранее был загружен через класс WebClient, но я пытаюсь реализовать новое решение с FtpWebRequest для этого MSFT-примера .
Эта ошибка выдает при вызове request.GetResponse()
ниже:
string remoteFilePath =
ConfigWrapper.GetEncryptedString(
"FtpFeedPath",
@"ftp://subdomain.domain.com/folder/subfolder/file.xml.gz");
string tempFilePath = Path.GetTempPath() + @"\ftpFile.gz";
string fileExtractName = Path.GetTempPath() + @"\ftpFile\ftpFile.xml";
if (!Directory.Exists(Path.GetDirectoryName(fileExtractName)))
{
Directory.CreateDirectory(Path.GetDirectoryName(fileExtractName));
}
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create(remoteFilePath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Timeout = -1;
request.UseBinary = true;
request.KeepAlive = true;
request.UsePassive = false;
request.Credentials = new NetworkCredential(
ConfigWrapper.GetEncryptedString(
"FtpUserName",
"123456"),
ConfigWrapper.GetEncryptedString(
"FtpPassword",
"password"),
remoteFilePath);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine($"Download Complete, status{response.StatusDescription}");
reader.Close();
response.Close();
Копание в исключении показывает это сообщение:
ContentType = '((System.Net.WebException)ex).Response.ContentType' threw an exception of type 'System.NotImplementedException'
Большинство других ответов StackOverflow, относящихся к этой проблеме, похоже, разрешаются после изменения свойства KeepAlive
. Это не тот случай, здесь. Другая распространенная рекомендация - получить сетевую трассировку, но большинство сообщений не обсуждали проблему и не извлекали трассировку. След ниже.
Одна вещь, которая выделяется из трассировки, заключается в том, что команда USER
FTP включает полный путь к файлу, а не только имя пользователя сервера. Есть ли способ сначала установить аутентификацию на сервере, прежде чем запрашивать загрузку с полным путем? Пример MSFT, похоже, сразу указывает весь путь.
System.Net Information: 0 : [25984] RAS supported: True
System.Net Information: 0 : [25984] FtpControlStream#43231651 - Created
connection from XX.XX.XX.XX:65106 to XX.XX.XX.XX:21.
System.Net Information: 0 : [25984] Associating FtpWebRequest#58529038 with FtpControlStream#43231651
System.Net Information: 0 : [25984] FtpControlStream#43231651 - Received response [220 Remote FTP Server. All transfers are logged.]
System.Net Information: 0 : [25984] FtpControlStream#43231651 - Sending command [USER ftp://subdomain.domain.com/folder/subfolder/file.xml.gz\1850771]
System.Net Information: 0 : [25984] FtpWebRequest#58529038::(Releasing FTP connection#43231651.)
System.Net Error: 0 : [25984] Exception in FtpWebRequest#58529038::GetResponse - The underlying connection was closed: The server committed a protocol violation..
at System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
at System.Net.FtpWebRequest.RequestCallback(Object obj)
at System.Net.CommandStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
at System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
at System.Net.FtpWebRequest.GetResponse()