Benutzer mit den meisten Antworten
C# FTP Request timeout mit embedded Device

Frage
-
Hallo,
ich habe hier ein Power Quality Messgerät, welches auf seiner SDKarte eine Reihe von Dateien mit Messdaten und anderem, z.B. Kurvenformen von Störungen etc. speichert. Diese Dateien müssen per FTP Verbindung heruntergeladen werden für weitere Verarbeitung.
Das Problem ist, daß keine Verbindung zustande kommt, sondern immer nur eine Timeout Exception geworfen wird.
Anfrage beim Hersteller ergab, daß für FTP bei Benutzung von FileZilla folgende Einstellungen getroffen werden müssen:
- Transfer mode passiv
- Anzahl simultaner Verbindungen auf "1" begrenzen
Im FileZilla lässt sich das einstellen, und dann kann auch auf das Gerät mit FTP zugegriffen werden.
In C# ist es nur möglich, den passiv mode zu verwenden. Ich habe nichts darüber gefunden, ob und wie man die Anzahl der simultanen Verbindungen (ich denke mal, es ist der CommandChannel und der TransferChannel gemeint) auf 1 begrenzen kann.
Ohne diese Einstellungen kommt auch beim FileZilla meist noch nicht mal ein connect zustande.
Zum Test benutze ich folgenden Code:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://172.16.0.199/"); request.UsePassive = true; request.Credentials = new NetworkCredential("PQube", "PQube"); request.KeepAlive = true; request.Method = WebRequestMethods.Ftp.ListDirectoryDetails; FtpWebResponse response = null; try { response = (FtpWebResponse)request.GetResponse(); Stream responseStream = response.GetResponseStream(); StreamReader reader = new StreamReader(responseStream); Console.WriteLine(reader.ReadToEnd()); Console.WriteLine("Directory List Complete, status {0}", response.StatusDescription); reader.Close();
responseStream.Close(); response.Close(); } catch (WebException web) { Console.WriteLine("Web Exception: " + web.Message); }Weiß jemand Rat ?
- Bearbeitet GerhardBiebl Dienstag, 29. Januar 2013 11:33
Antworten
-
Hallo Marcel,
Heureka!
Endlich hat es funktioniert, nachdem ich den DataConnectionType des FtpClient von FtpDataConnectionType.PASV auf FtpDataConnectionType.PASVEX geändert habe !
Jetzt geht der Connect durch, und auch die Directory entries kann ich empfangen.
Vielen Dank !
- Als Antwort markiert Marcel RomaModerator Donnerstag, 31. Januar 2013 14:39
Alle Antworten
-
Hallo Gerhard,
dann versuch's doch mal bitte mit ServicePoint.ConnectionLimit:
request.ServicePoint.ConnectionLimit = 1;
Der Standardwert ist 2, wenn ich mich nicht irre.P.S. Sollte das Problem weiter bestehen, muss festgestellt werden, an welchem Punkt dein Program aussteigt. Dazu erstellst Du eine Ablaufverfolgung. In der app.config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <sources> <source name="System.Net" tracemode="includehex" maxdatasize="1024"> <listeners> <add name="System.Net"/> </listeners> </source> <source name="System.Net.Sockets"> <listeners> <add name="System.Net"/> </listeners> </source> <source name="System.Net.Cache"> <listeners> <add name="System.Net"/> </listeners> </source> </sources> <switches> <add name="System.Net" value="Verbose"/> <add name="System.Net.Sockets" value="Verbose"/> <add name="System.Net.Cache" value="Verbose"/> </switches> <sharedListeners> <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="network.log" /> </sharedListeners> <trace autoflush="true"/> </system.diagnostics> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> </configuration>
In den Projekteigenschaften, Registerkarte "Erstellen", muss dann noch die "TRACE-Konstante definieren"-Option aktiviert werden. Poste anschließend die anonymisierte network.log.
Gruß
Marcel
- Bearbeitet Marcel RomaModerator Dienstag, 29. Januar 2013 12:23 P.S.
-
Die Stelle im Quellcode, an der das testprogramm hängen bleibt, ist eindeutig die Zeile mit dem "GetResponse". Ich werde aber noch einen Trace versuchen.
Zwischenzeitlich habe ich mir mal mit dem Wireshark angesehen, was da an Kommunikation läuft.
Der FileZilla sendet zuerst einen tcp SYN zum Gerät, das antwortet mit 220: Service ready for new user. Anschliessend sendet FileZilla den Username, der mit "331: user name ok, need password" quittiert wird. Dann sendet FileZilla das Password, quittiert mit "230: user logged in".
Anschliessend wird der ftp request "PWD" gesendet, der vom Gerät beantwortet wird.
Mit dem Testprogramm dagegen:
Das Programm kommt bis zu dem Punkt, wo vom Gerät die Meldung kommt: "220: Service ready for new User". Danach wird merkwürdigerweise vom PC ein tcp Ack und danach ein ftp RST, ACK gesendet ? Kein Username oder so, und dann ist Ende Gelände.
-
Ja, die Credentials werden nach der 220-Antwort scheinbar nicht gesendet. Kann dir vielleicht eine Alternative anbieten:
using System; using System.Net; using System.Net.FtpClient; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { FtpClient ftp = new FtpClient(); ftp.DataConnectionType = FtpDataConnectionType.PASV; ftp.Host = "172.16.0.199"; ftp.Credentials = new NetworkCredential("PQube", "PQube"); ftp.Connect(); if (ftp.IsConnected) { var workingDirectory = ftp.GetWorkingDirectory(); var items = ftp.GetListing(workingDirectory, FtpListOption.NameList); foreach (var item in items) Console.WriteLine(item.Name); } Console.ReadKey(true); } } }
Klappt denn die Kommunikation mit dem Server von der Befehlszeileneingabe problemlos? -
Hallo Marcel,
ich hab das verlinkte Projekt geladen, ich bekomme aber den namespace nicht in mein Projekt.
Wenn ich die dll als Referenz einbinde, dann ist zunächst alles scheinbar in Ordnung, und ih kann die Using Direktive benutzen, auch der Typ wird highlighted. Beim nächsten build heisst es aber, daß es den Namespace System.Net.FtpClient nicht gäbe.
Schöne Grüße, Gerhard
Das oben hat sich erledigt: ich hatte .NET 4.0 ClientProfile angegeben;nach Änderung auf .NET 4.0 war das Problem weg.
Leider hat sich dadurch in Bezug auf die Kommunikation nichts verbessert, obwohl ich auf Verdacht inzwischen das TCP Modul des Gerätes getauscht und die Firmware upgedatet habe, bleibt er immer noch bei den Credentials hängen.
- Bearbeitet GerhardBiebl Donnerstag, 31. Januar 2013 14:16
-
Hallo Marcel,
Heureka!
Endlich hat es funktioniert, nachdem ich den DataConnectionType des FtpClient von FtpDataConnectionType.PASV auf FtpDataConnectionType.PASVEX geändert habe !
Jetzt geht der Connect durch, und auch die Directory entries kann ich empfangen.
Vielen Dank !
- Als Antwort markiert Marcel RomaModerator Donnerstag, 31. Januar 2013 14:39