Laden...

Asynchrone FTP-Socket Statuszuordung im passiven Modus

Erstellt von mosspower vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.181 Views
mosspower Themenstarter:in
456 Beiträge seit 2007
vor 15 Jahren
Asynchrone FTP-Socket Statuszuordung im passiven Modus

Hallo "Kollegen",

ich hätte bezüglich Sockets zwei Fragen. Ich habe hier erst angefangen, mit Sockets zu programmieren.

1). Warum laufen bei mir auf meinem System, sowohl in der Arbeit als auch zu Hause meine Programmcodes nicht, wie in vielen Beispielen aus dem Internet? Das Problem ist, dass mein Programm läuft, wenn ich ein Thread.Sleep reinbaue, teilweise sogar auf 500 Millisekunden setzen muss, dann funzzt meine Anwendung einwandfrei. Natürlich ist das nicht die Lösung, ich werde das asynchron machen, jedoch wüsste ich schon gerne, warum bei allen Beispielen im Netz das so angegeben wird (Socket.Available, bzw. in Verbindung mit readBytes, nach dem letzten Receive) und es bei mir aber nicht funzzt, ohne den Timeout.

2). Thema gleichzeitiger Down- und Upload von mehreren Dateien. Ich dachte, ich kann hier immer das gleiche Socket nehmen, da ich ja ein extra Transfersocket aufmachen muss (Befehl PASV), aber das scheint nicht zu gehen. Ich möchte mich hier nur vergewissern. Ist es wirklich so, dass ich für jeden Up- bzw. Download ein eigens Socket instanzieren muss (inklusive Verbindungsaufbau)?

Gruß und danke schon einmal für etwaige Antworten im Voraus.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo mosspower,

zu Frage eins kann ich nichts sagen, aber bei Frage zwei geht es um FTP, oder? Je nachdem, ob passives oder aktives FTP läuft alles über die eine Verbindung oder es werden neue Verbindungen aufgemacht.

Beachte in Zukunft bitte [Hinweis] Wie poste ich richtig? Punkt 1.2.

herbivore

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 15 Jahren

Hallo herbivore,

zu 2) Ich habe passives FTP verwendet. Ich denke es geht nicht, wenn man bei einem Hauptsocket mehrere Datensockets (die benötigt werden für passiven Modus) die gleichzeitig in Threads Up-oder Download durchführen.

Ich habe mir mal kurz Gedanken darüber gemacht. Es macht imo glaube ich keinen Sinn, dass man z.B. mittels einer Regex Dateien in Threads gleichzeitig downloaded (das macht nicht mal Filezilla). Angebracht erscheint mir (was bei mir auch geht in meinem Client), dass alle Files synchron downgeloaded werden, aber jedes File einzeln asynchron, soll bedeuten, dass es eine Schnittstelle gibt, um z.B. eine Fortschrittsanzeige zu implementieren.

Nehmen wir mal ein Beispiel. Ich verbinde mich auf einen FTP Server und im Hauptverzeichnis matchen 30 Dateien meine übergebene Regex. Dann downloade ich die doch nacheinander runter (mit eben der Möglichkeit für Fortschrittsanzeige) aber doch nicht alle gleichzeitig, oder? Kennt ihr Programme, die so vorgehen, und wenn ja, was ist zu tun? In dem letzteren Fall müssten doch dann immer eigene Verbindungen aufgebaut werden oder läuft das über das "Hauptsocket" - was bei mir aber gegenwärtig kracht.

Ich kenne das Beispiel z.B. von Firefox, wenn ich 20 große Dateien downloade, dann werden die alle asynchron downgeloaded und ich sehe das, bei Filezilla ist es synchron.

Macht es Sinn, hier asynchron downzuloaden? Eigentlich nicht, oder?

P.S. Sorry wegen dem falschen Eingangspostthema, bzw. Nichteinhaltung von Postinregeln

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 15 Jahren

Hallo,

ich habe heute einen dreiviertel Tag "verbraten" und komme nicht weiter. Es ist wirklich so, dass manchmal einfach nix übermittelt wird und dann nach einer Unterbrechung wieder Daten verfügbar sind ....

dieser Code z.B. macht mich echt wahnsinnig ...


 byte[] buffer = new byte[512];

        while(true) {
          int length = transferSocket.
            Receive(buffer, buffer.Length, SocketFlags.None);
           transferData.Append(Encoding.ASCII.GetString(buffer, 0, length ));

           if(transferSocket.Available == 0) {
             Thread.Sleep(2000);

             if(transferSocket.Available == 0) {
               break;
             }
           }
        }


Bei Thread.Sleep 1500 fehlt die Hälfte der Daten ... das kann doch nicht sein. Wie kann man denn das lösen. Alle Tutorials im Inet machen das genauso oder fragen am Ende der Schleife die Länge der gelesenen Bytes und vergleichen die mit dem Char-Array .. jedoch ist das bei mir leer oder kleiner und dann, wenn im Debugmodus mit Breakpoint, füllt sich der "Käse" dann wieder. Wie soll ich da ein lauffähiges Produkt programmieren? Ich kann doch nicht jedesmal 2-5 Sekunden unterbrechen, nur weil noch Daten kommen könnten.

Kann mir da jemand helfen? Ich schaue noch mal, ob das mit Asynch auch so aussieht. Wenn ja, dann kann ich meinen "Socket-Ausflug" gleich wieder vergessen. 🙁

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 15 Jahren

OK, ich bin jetzt wieder ein bißchen weiter ...
das Problem wurde gelöst, indem ich im "Hauptsocket" den Status nach 226, also Transfer complete) abfrage. Der Listbefehl benötigt ja, neben dem (Up- und Downloaden) eigene Verbindungen, die mittels sog. "Untersockets" realisiert werden.

Hier mal der angepasste Quellcode ...


        
        byte[] buffer = new byte[FtpClient.BUFFER_SIZE];
        DateTime timeout = DateTime.Now.AddSeconds(FtpClient.MAX_TIMEOUT.TotalSeconds);
    
        while(DateTime.Now < timeout) {
          // Check whether data on
          // transfer socket are available
          if(transferSocket.Available > 0) {
            // Read data
            int readBytes = transferSocket.
              Receive(buffer, buffer.Length, SocketFlags.None);
            transferData.Append(Encoding.ASCII.GetString(buffer, 0, readBytes));
          }
          else {
            // Check whether status message 
            // on main socket is available
            if(this.socket.Available > 0) {
              this.ReadResponse(FtpStatusCode.ClosingData);

              if(debug) {
                Console.WriteLine(this.response);
              }

              // Exit loop
              if(this.statusCode == FtpStatusCode.ClosingData.GetHashCode()) {
                break;
              }
            }
          }
        }

Jetzt wird solange die Schleife durchlaufen, bis entweder ein Timeout auftritt oder aber das Hauptsocket 226 meldet.

Jetzt habe ich trotzdem noch eine FTP-Verständnisfrage. Immer, wenn eine Aktion im passiven Modus erfolgreich abgeschlossen wurde (Download, Upload, Listing von Dateien und Verzeichnissen), gibt das Hauptsocket eine Meldung raus, z.B. 226 Transfer complete. Wie kann ich jetzt herausfinden, welche Meldung zu welchem Socket im passiven Modus gehört?

Kann mir da jemand helfen, bzw. einen Link posten? Problem ist, wenn ich z.B. 10 Downloads starte (synchron in Threads) und ich währenddessen ein Listing durchführe (siehe Quellcode oben), dann weiss ich ja nicht, wenn 226 auf der Console landet, auf was sich das bezieht, auf Download oder Listing. Das muss man doch irgendswie auseinanderhalten können?

Gruß und Danke schonmal für etwaige Antworten im Voraus.

P.S. Das mit den mehreren Verbindungen geht, denn Filezilla macht das auch so. Sogar laufen alle Downloads weiter, auch wenn beim Hauptsocket Verbindung geschlossen wurde.