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
Vous devez vous connecter pour publier un commentaire.
Veux juste renforcer ScottE du diagnostic, et d'être plus précis. Délai d'attente est le plus susceptible de la question.
.Net de la mise en œuvre de FtpWebRequest est erroné ou le document MSDN a une faute de frappe, la valeur par défaut de FtpWebRequest.Délai d'attente n'est pas -1 (Infini). Il est 100 000 (100 secondes).
En outre, il ya un autre problème de délai d'attente. Quelques tests ont montré que responseStream a toujours une valeur de délai d'expiration de 300000 (300 secondes). Je ne sais pas comment cette valeur est assignée. De toute façon, cette valeur doit être modifiée pour accueillir de gros fichiers.
En résumé, la solution est de mettre FtpWebRequest.Délai d'attente et de Flux.Délai d'attente pour une valeur suffisamment élevée.
Voici un bon fil de choses à essayer:
http://social.msdn.microsoft.com/Forums/en/ncl/thread/47634ec2-4d40-4d3f-b075-8cc92bfa2b24
Augmenter le délai d'attente est probablement une bonne idée au moins.
Cela pourrait être un symptôme d'un problème avec les paramètres de votre Pare-feu Windows. La désactivation du "Application Layer Gateway Service" dans les "services" de l'interface fixe pour moi.
Ce thread a beaucoup d'informations:
http://forum.parallels.com/pda/index.php/t-57966.html