La connexion sous-jacente a été fermée: une erreur inattendue s'est produite sur une réception

Je suis ici parce que j'ai un problème lors du téléchargement de certains fichiers via le protocole ftp. C'est bizarre parce qu'il se produit de temps en temps et même pour un seul et même fichier.

Juste une précision: je suis le téléchargement de fichiers de très grande taille (à partir de 500 Mo à 30Go)

Voici le genre d'Exceptions renvoyées par ma fonction : (désolé, c'est en français)

System.Net.WebException: La connexion sous-jacente a été fermée : Une erreur inattendue s'est produite lors de la réception.
à System.Net.FtpWebRequest.CheckError()
à System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
à System.IO.Stream.Close()
à System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
à System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
à System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
à System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
à System.Net.CommandStream.Abort(Exception e)
à System.Net.CommandStream.CheckContinuePipeline()
à System.Net.FtpDataStream.System.Net.ICloseEx.CloseEx(CloseExState closeState)
à System.Net.FtpDataStream.Dispose(Boolean disposing)
à System.IO.Stream.Close()
à UtilityClasses.FTP.Download(String srcDirectoryPath, String file, String destDirectoryPath)

Voici le code utilisé pour télécharger :

des méthodes de téléchargement :

public Dictionary<string, object> Download(string srcDirectoryPath, string file, string destDirectoryPath, int attemptLimitNb, int delay)
{
int attemptNb = 0;
bool downloadFailed;
Dictionary<string, object> result = new Dictionary<string,object>();
do
{ 
attemptNb++;
result = Download(srcDirectoryPath, file, destDirectoryPath);
downloadFailed = result["downloadfailed"] != null;
if (downloadFailed) Thread.Sleep((int)(1000 * delay));
}
while (downloadFailed && attemptNb < attemptLimitNb);
return result;
}
public Dictionary<string, object> Download(string srcDirectoryPath, string file, string destDirectoryPath)
{
Exception downloadFailed = null;
Dictionary<string, object> result = new Dictionary<string, object>();
bool fileFound = false;
try
{
if (destDirectoryPath == null || !Directory.Exists(destDirectoryPath)) throw new Exception("Download destination path does not exist");
if (file != null && file != "")
{
if (file.Contains("/"))
{
throw new Exception("Invalid file name. Impossible to download");
}
Uri serverUri;
if (srcDirectoryPath == null || srcDirectoryPath == "")
{
serverUri = new Uri("ftp://" + this.Server + "/" + file);
}
else if (Regex.IsMatch(srcDirectoryPath, "^/.*$") || Regex.IsMatch(srcDirectoryPath, "^.*/$"))
{
throw new Exception("Path must not start and end with '/'");
}
else
{
serverUri = new Uri("ftp://" + this.Server + "/" + srcDirectoryPath + "/" + file);
}
if (serverUri.Scheme != Uri.UriSchemeFtp) throw new Exception("server URI Scheme does not match  FTP URI Scheme");
if (Exists(srcDirectoryPath, file))
{
fileFound = true;
FtpWebRequest downloadRequest = (FtpWebRequest)FtpWebRequest.Create(serverUri);
downloadRequest.Credentials = new NetworkCredential(UserName, Password);
downloadRequest.KeepAlive = false;
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)downloadRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream fileStream = new FileStream(Path.Combine(destDirectoryPath, file), FileMode.Create);
byte[] buffer = new byte[2000];
int read = 0;
try
{
do
{
read = responseStream.Read(buffer, 0, buffer.Length);
fileStream.Write(buffer, 0, read);
fileStream.Flush();
}
while (read != 0);
}
catch (Exception e)
{
fileStream.Close();
responseStream.Close();
response.Close();
throw e;
}
fileStream.Close();
responseStream.Close();
response.Close();
}
}
}
catch (WebException webExcptn)
{
downloadFailed = webExcptn;
}
finally
{
result.Add("filefound", fileFound);
result.Add("downloadfailed", downloadFailed);
}
return result;
}

la méthode Exists :

public bool Exists(string srcPath, string elementName)
{
if (elementName == null || elementName == "")
{
return false;
}
Uri serverUri;
bool res = false;
if (srcPath == null || srcPath == "")
{
serverUri = new Uri("ftp://" + this.Server);
}
else if (Regex.IsMatch(srcPath, "^/.*$") || Regex.IsMatch(srcPath, "^.*/$"))
{
throw new Exception("Path must not start and end with '/'");
}
else
{
serverUri = new Uri("ftp://" + this.Server + "/" + srcPath);
}
if (serverUri.Scheme != Uri.UriSchemeFtp) throw new Exception("server URI Scheme does not match  FTP URI Scheme");
FtpWebRequest listingRequest = (FtpWebRequest)FtpWebRequest.Create(serverUri);
listingRequest.Credentials = new NetworkCredential(UserName, Password);
listingRequest.KeepAlive = false;
listingRequest.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)listingRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
string ftpElementName;
do
{
ftpElementName = Path.GetFileName(streamReader.ReadLine());
if (ftpElementName == null) break;
else
{
string pattern = "^" + elementName.Replace("[", "\\[").Replace("]", "\\]").Replace("+", "[+]").Replace(".", "[.]") + "$";
if (Regex.IsMatch(ftpElementName, pattern, RegexOptions.IgnoreCase))
{
res = true;
}
}
}
while (ftpElementName != null && !res);
streamReader.Close();
responseStream.Close();
response.Close();
return res;
}

C'est peut-être un problème de délai d'attente, mais je ne sais pas vraiment. J'ai cherché pendant longtemps une réponse mais sans succès. Peut-être que certains d'entre vous aura une solution.

///

EDIT : Quelques progrès :

J'ai testé mon code en mode debug avec VS et en fait l'Exception ci-dessus est la conséquence du précédent. (Je ne Pouvais pas le savoir car j'ai seulement écrit la dernière Exception retournée dans un fichier journal)

Ici est à l'origine d'exception :

Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

La deuxième exception est causée par cette partie de la méthode de Téléchargement de code :

catch (Exception e)
{
fileStream.Close();
responseStream.Close();  //<<<<<<<<<<<<<<
response.Close();
throw e;
}

- Je garder mes investigations, mais il semble que le "délai d'attente pb de" l'hypothèse la plus cohérente. Je vais essayer avec une grande valeur de délai d'expiration de ce soir.

source d'informationauteur Hariboox