Laden...

FTP GetfileSize geht nur mit KeepAlive Parameter. bringt aber 550er Fehler nach einiger Zeit

Erstellt von TheDevil vor 5 Jahren Letzter Beitrag vor 5 Jahren 2.162 Views
T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren
FTP GetfileSize geht nur mit KeepAlive Parameter. bringt aber 550er Fehler nach einiger Zeit

Hallo *all,

mein Problem stellt sich wie folgt dar.

Ich lade mehrere Dateien von einem FTP Server herunter. Vorher wird natürlich das verzeichnis eingelesen und dann in einer Schleife alle Dateien abgearbeitet.

Nun möchte ich vorher noch die Größe des Files abholen und danach mit dem File auf dem PC vergleichen. Und hier beginnt es nun merkwürdig zu werden.

Sobald ich in den Parametern KeepAlive = false; einstelle erhalte ich umgehend einen FTP 550 Fehlercode (Datei nicht vorhanden oder Zugriff nicht erlaubt). Stelle ich auf KeepAlive = true; um kann ich das Programm ohne Probleme laufen lassen, bis zu dem Zeitpunkt an dem anscheinene zu viele Verbindungen aufgebaut werden und er mir dann wieder den 550 Code um die Ohen haut.

Hat jemand diees Verhalten bei einem FTP Server auch schon mal gehabt ? Wie gesagt wenn ich KeepAlive = true; einsetze kann ich die Größe "erfragen", das File downloaden etc...

Gruß,
Ralf

16.807 Beiträge seit 2008
vor 5 Jahren

Magst Du den Leuten auch verraten, mit was Du mit dem FTP Server sprichst?
An FTP selbst liegt das jedenfalls nicht; das FTP Protokoll kennt ein SIZE Command.

T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren

Hallo


public FtpProvider(string serverAdress, string login, string password)
{
           this.ServerAdress = serverAdress;
           this.Login = login;
           this.Password = password;
           this.PassiveMode = true;
           this.UseBinary = true;
           this.Proxy = null;
           this.KeepAlive = false;
           this.ConnectionGroupName = "MyFtpGroup";
           this.ConnectionLimit = 9;

}

public void GetFileSize(string file, out long filesize, out bool isOK, out string info)
{
          isOK = false;
          info = "";
          filesize = 0;

          FtpWebRequest request = GetFtpRequest(file, WebRequestMethods.Ftp.GetFileSize);

          WebResponse response = request.GetResponse();

          try
         {
                 filesize = response.ContentLength;
                 isOK = true;
                 return;
         }
         catch (Exception ex)
         {
                info = ex.ToString();
         }
         finally
         {
         response.Close();
         }
         }

private FtpWebRequest GetFtpRequest(string path, string method)
{
              //FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" +                                             ServerAdress + "/" + path));
             FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(ServerAdress                             + "/" + path));
             request.Method = method;
             request.UseBinary = this.UseBinary;
             request.Credentials = new NetworkCredential(Login, Password);
             request.Proxy = this.Proxy;
             request.KeepAlive = this.KeepAlive;
             request.UsePassive = this.PassiveMode;
             request.ConnectionGroupName = this.ConnectionGroupName;
             request.ServicePoint.ConnectionLimit = this.ConnectionLimit;
             return request;
}


  1. Versuch
16.807 Beiträge seit 2008
vor 5 Jahren

Also am Code sehe ich jetzt nicht, woran das liegen könnte, denn Du verwendest bereits WebRequestMethods.Ftp.GetFileSize

Aber die GetFileSize Methode verletzt so ziemlich jedes .NET Error Handling Prinzip 😉
Wenn Du einen Fehler hast, dann werf die Exception. Es gibt keinen Sinn, dass Du den Text abfängst und dann über einen out-Parameter ausgibst.
Zudem macht es keinen Sinn, dass die Größe der Methode nicht als Rückgabe erfolgt.

Die gesamte Methode kann folgendermaßen vereinfacht werden:


public int GetFileSize(string file)
{
          FtpWebRequest request = GetFtpRequest(file, WebRequestMethods.Ftp.GetFileSize);
          using(WebResponse response = request.GetResponse())
          {
                 return response.ContentLength;
          }
}

Ich vermute den Fehler durch eine ungültige Eingabe von file, zB weil es keine gültige FTP Uri ist.

T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren

Hallo.

erst einmal Danke für die schnell Info.

An der url kann es eigentlich ja nicht liegen da ja wie geschrieben wenn ich
KeepAlive auf true setze alles so weit läuft wie es soll. Ich ändere ja nur ein false in ein true.

Und genau das verstehe ich eben einfach nicht warum hier der FTP Server ein 550er zurückgibt.

Gruß,
Ralf

16.807 Beiträge seit 2008
vor 5 Jahren

Mal geprüft, ob es am Server und nicht am Client liegt?

T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren

Hallo.

Den Kollegen auf der FTP Server Seite sind diese Probleme nicht bekannt.
Ich gucke mal ob ich vielleicht noch andere Klassen dazu finde.
Ich habe das ganze nun auch mal auf einem anderen PC ausprobiert. Dort
"schmiert" die Übertragung der einzelnen Files nach ca. 26 statt auf dem anderen
Rechner nach 9 Files ab ... alles sehr sehr merkwürdig.

Vielen Dank noch mal für die hilfreichen Tipps und die Unterstützung.

Gruß,
Ralf

T
2.219 Beiträge seit 2008
vor 5 Jahren

Haben deine Kollegen auch mal die Logs vom FTP Server geprüft?
Wenn dort Logging mit genug Details aktiv sind, sollte da auch eine Info kommen.
Ebenfalls solltest du auch mit den FTP Leuten sicher gehen, dass du auch Zugriff auf die Datei hast.
550 heißt nicht nur, Datei nicht vorhanden, sondern auch keinen Zugriff.
Kann also auch ein Rechte Problem mit den Dateien sein.

Nachtrag:
Wenn möglich, solltest du neben der Dateigröße auch Zeitstempel abfragen.
Es kann auch Fälle geben in denen die Größe identisch ist, die Datei aber geändert wurde.
Ist zwar ein seltener Fall, kann aber vorkommen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren

Hallo.

So nun habe ich mal Versuch eder unterschielichsten Art unternommen. Was geht ist ca. 100 Files direkt ohne GetFileSize downzuloaden. Allerdings auch MANCHMAL mit einer Exception nach ca. 50 Files. Den Aufruf habe ich dann in eine Schleife gepackt die bei einem Fehle max. 3 mal durchgeht. Kommt ein Fehler wird direkt ein 2. Zugriff (download) versucht und der funktioniert dann auch dezeit sofort (warum auch immer).

Jetzt habe ich die Download Methode ausgesternt und durch GetFileSize ersetzt. Die Credentials etc... sind genau die selben (außer der Methode). Kopiert aus der Download-Methode. Dort erhalte ich nach ca. 69 Files die 550er Meldung Dateiname nicht vorhanden oder Zugriff verweigert. Setzte ich nun allerdings einen Sleep von 10 Sekunden für jeden GetFilesize ein dauert das naturgegebenermaßen ewig aber es kommt keine Fehlermeldung und der Job läuft durch.

Mit den Kollegen des "FTP Server" Systems habe ich gesprochen. Keine Beschränkungen.
Geschrieben sei noch das ich auf VS 2008 "laufe". Vielleicht ist das ja auch das Problem....

Für jede Info / Idee wäre ich dankbar 😃

Gruß aus dem hohen Norden der Republik.

Gruß,
Ralf

T
2.219 Beiträge seit 2008
vor 5 Jahren

An deiner Stelle würde ich ein Update auf VS 2017 in betracht ziehen.
Aktuell kannst du mit VS2008 nur bis .NET 3.5 gehen.
Mit VS 2017 könntest du mal .NET 4.6/4.7 testen.

Lösungen mit Thread.Sleep kannst du gleich verwerfen.
Das ist gefummeln und keine Lösung.
Mach mal einen Umstieg und teste es dann mal mit neuer .NET Version.
Vielleicht hat sich das Problem damit erledigt.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren

Hallo.

Ja das mit 2017 werde ich wohl morgen testen. Ich werde dann berichten.

Das mit dem Sleep war auch nur um zu sehen ob es evtl. dann gehen WÜRDE und
das damit die Serverantwort "File nicht vorhanden oder Zugriff nicht erlaubt" in das
Reich "das stimmt nicht" gebeamt werden kann 😃

Vielen Dank einstweilen.

Gruß,
Ralf

T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren

Hallo und guten Morgen,

also ich habe nun das ganze mal mit 2017 und FluentFTP ausprobiert.
Derzeit keine Probleme.

Danke bei allen für die Unterstütrzung / Anmerkungen.

Gruß,
Ralf

16.807 Beiträge seit 2008
vor 5 Jahren

Hint: VS 2017 ist eine IDE und keine Runtime.
Also "nur ein Editor".

Die Angabe "mit VS 2017" geht es, ist inhaltlich also nichtsagend, weil es die Runtime ignoriert.
Man kann auch ohne VS 2017 problemlos in C# mit .NET programmieren - zB mit Notepad.

T
TheDevil Themenstarter:in
9 Beiträge seit 2013
vor 5 Jahren

Hallo.

So ein kleines update. Ich arbeite noch mit .net 3.5 Framework.

Was ich ersehen konnte ist folgendes.
Ich lade das Verzeichnis vom FTP Server was überhaupt kein Problem darstellt. Wenn ich hier als KeepAlive ein false einstelle und danach ein GetFileSize versuche dann wird von dem Request kein Type I gesendet. Folglich befindet sich der Request noch im Ascii Mode und das mag das Command "Size" nun mal nicht.

Wenn ich das Laden des Verzeichnisses mit KeepAlive = true asuübe bleibt ja die Verbindung bestehen und somit auch der vom GetDirectoryList gesendete Type I ... die folgende GetFileSize versuche und dazu die entsprechenden Downloads klappen dann auch. Allerdings nur eine Zeit lang und auf einmal befindet sich ein GetFileSize wieder im ASCII Mode ... Obwohl das ganuz hier lediglich in einer ForEach Schleife läuft mit immer den selben Parametern.

Ich hoffe Ihr versteht mich 😃

gruß,
Ralf