vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Zippen wie die Profis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2017
 
zurück
Rubrik: Internet/Netzwerk   |   VB-Versionen: VB5, VB601.12.01
FTP - File Transfer Protokoll, Teil 2

Der zweite Teil unseres "FTP"-Workshops widmet sich nun dem Up- und Download von Dateien. Auch möchten wir Ihnen zeigen, wie sich ein abgebrochener Up- oder Download-Vorgang zu einem späteren Zeitpunkt wieder fortsetzen lässt. Somit sollten Sie am Ende dieses Workshops über alle Informationen verfügen, um Ihren eigenen FTP-Clienten zu programmieren.

Autor:  Dieter Otter / Matthias VolkBewertung:     [ Jetzt bewerten ]Views:  21.902 

Neue Version! sevEingabe 3.0 (für VB6 und VBA)
Das Eingabe-Control der Superlative! Noch besser und noch leistungsfähiger!
Jetzt zum Einführungspreis       - Aktionspreis nur für kurze Zeit gültig -

Im ersten Teil unseres "FTP"-Workshops haben wir Ihnen die grundlegende Vorgehensweise für das Herstellen einer Verbindung zu einem externen FTP-Server, sowie alle hierfür notwendigen Befehle und Funktionen vorgestellt. Der zweite Teil widmet sich nun dem Up- und Download von Dateien. Auch möchten wir Ihnen zeigen, wie sich ein abgebrochener Up- oder Download-Vorgang zu einem späteren Zeitpunkt wieder fortsetzen lässt. Somit sollten Sie am Ende dieses Workshops über alle Informationen verfügen, um Ihren eigenen FTP-Clienten zu programmieren.

Kurzer Rückblick

Mit den aus Teil 1 vorgestellten Befehlen und Funktionen konnte bisher folgendes durchgeführt werden:

  • Anmelden und Verbinden mit dem FTP-Sever
  • Verzeichnisinformationen lesen und in einer Liste anzeigen
  • Wechseln in über- und untergeordnete Verzeichnisse und Inhalt anzeigen
  • Ermitteln der Dateigröße einer Datei
  • Verbindung beenden

Was jetzt noch fehlt, sind die entsprechenden Befehle, um eine auf der Festplatte lokal gespeicherte Datei in ein Verzeichnis des FTP-Servers hochzuladen (Upload), sowie umgekehrt eine auf dem FTP-Server vorhandene Datei lokal auf die Festplatte zu speichern (Download).

Download einer Datei

Beginnen wir mit dem Download-Vorgang. Für den Download von Dateien benötigen wir ein drittes Winsock-Steuerelement. Wir nennen es DownSock. Voraussetzung für einen erfolgreichen Download ist, dass zunächst eine Verbindung zum FTP-Server hergestellt wurde. Nachdem wir uns also am FTP-Server angemeldet haben und die Verbindung zustande gekommen ist, müssen wir zunächst wieder einen eindeutigen Port für das Empfangen der Daten öffnen. Ach so, ja - zuvor setzen wir den Übertragungsmode noch auf Binary.

' Datei downloaden
Friend Function DownloadFile(ByVal LocalFile As String, _
  ByVal ServerFile As String, _
  ByVal ServerFileSize As Long, _
  Optional ByVal StartDownloadAt As Long = 0)
 
  Dim TmpPort As Long
  Dim TmpPortStr As String
 
  ' Servermodus auf Binär stellen
  If SendCommand(OvermitBinary, CommandOk, CommandOk, _
    CommandFail) = False Then Exit Function
 
NewUniquePort:
  ' Port öffnen (für das Empfangen von Daten)
  TmpPort = 0
 
  ' Neuen Port ermitteln
  Call GetNewPort(TmpPort, TmpPortStr)
 
  ' Neuen Port öffnen
  With Downsock
    .Close
    .LocalPort = TmpPort
    .Listen
  End With
 
  ' neu geöffneten Port dem Server mitteilen
  If SendCommand(SetPort & TmpPortStr, CommandOk, _
    CommandOk, CommandFail, 0&, "Neuer Port geöffnet") = False Then
    Exit Function
  End If
 
  ' Download-Startposition setzen
  If SendCommand(ResumeTransfere & StartDownloadAt, _
    ResumingSupportet, CommandOk, _
    CommandNotImplemented) = False Then Exit Function
 
  ' Progressbar einstellen
  ' siehe Workshop-Projekt
 
  ' lokale Datei öffnen/erstellen
  FFile = FreeFile
  Open LocalFile For Binary As FFile
  Seek #FFile, StartDownloadAt + 1
 
  ' Download-Anfrage an Server senden
  TAbort = False
  TotalBytes = ServerFileSize
  OvermittedBytes = StartDownloadAt
  SendCommand Download & ServerFile, TransferComplete, _
    TransferComplete, DataConnectionClosed, TransferStart
 
  ' Warten bis das letzte Datenpäckchen übermittelt
  ' wurde
  Do
    DoEvents
  Loop Until Downsock.State <> sckConnected
 
  ' Socket schließen
  Downsock.Close
 
  ' Neue Datei schließen
  If FFile <> -1 Then
    Close FFile
    FFile = -1
  End If
 
  ' Falls abgebrochen wurde
  If TAbort = True Then
    ...
  End If
 
  ' Falls die Verbindung zur Datenleitung nicht
  ' aufgebaut werden konnte nochmals versuchen
  If LastServerCmd = DataConnectionError Then GoTo NewUniquePort
End Function

Wie Sie bereits an der Parameter-Deklaration der Prozedur DownloadFile erkennen können, lässt sich hier optional angeben, ob der Datei-Download ab einer bestimmten Datei-Position fortgesetzt werden soll (für den Fall, dass ein voriger Download abgebrochen wurde). Hierzu muss die entsprechende Position im Parameter StartDownloadAt angegeben werden.

Nach dem Senden der Download-Anfrage muss zunächst auf die Server-Antwort gewartet werden:

' Server-Verbindungsaufbau "genehmigen"
Private Sub DownSock_ConnectionRequest(ByVal requestID As Long)
  With Downsock
    If .State = sckListening Then
      .Close
      Do
        DoEvents
      Loop Until .State = sckClosed
      .Accept requestID
    End If
  End With
End Sub

Immer wenn der Server uns Daten schickt, wird das DataArrival-Ereignis ausgelöst. Hier müssen wir nun die empfangenen Daten speichern (an die lokal geöffnete Datei "anhängen"). Desweiteren bietet sich hier auch bestens die Gelegenheit, eine evtl. vorhandene Statusanzeige zu aktualisieren:

' Server Daten erreichen uns
Private Sub DownSock_DataArrival(ByVal bytestotal As Long)
  Dim TmpData As String
 
  ' Falls keine Bytes oder lokale Datei nicht
  ' geöffnet, Prozedur verlassen
  If bytestotal = 0 Or FFile = -1 Then Exit Sub
 
  ' Bisher empfangene Bytes aufaddieren
  OvermittedBytes = OvermittedBytes + bytestotal
 
  ' Daten an die lokal geöffnete Datei "anhängen"
  Downsock.GetData TmpData
  Put #FFile, , TmpData
 
  ' Download-Fortschritt aktualisieren
  ShowProgress picProgress, OvermittedBytes, 0, TotalBytes
End Sub

Abbrechen eines Up-/Downloads

Natürlich sollten wir auch eine Möglichkeit vorsehen, dass man einen Up- oder Download jederzeit manuell (per Knopdruck) abbrechen kann. Hierzu speichern wir uns den Abbruch in der Variablen TAbort. Während des Up- bzw. Downloads wird diese Variable ständig abgefragt, so dass die Schleife für das Uploaden bzw. Downloaden der Datenpakete beendet werden kann.

' Dateiübertragung abbrechen
Friend Function TransfereAbort()
  ' Abbruch-Kommando an den Server schicken
  SendCommand AbortTransfere, TransferComplete, _
    TransferComplete, -1&
 
  ' Abbruch-Variable auf True setzen
  TAbort = True
End Function

Upload einer Datei

Für den Upload-Vorgang verwenden wir ebenfalls das "neue" Downsock-Control. Der Upload selbst erfolgt immer in kleinen Datenpaketen, welche nach und nach an den FTP-Server geschickt werden. Jedesmal, wenn wir ein Datenpaket verschickt haben, müssen wir warten, bis der Server die Daten erhalten und bestätigt hat. Dann folgt das nächste - eben solange, bis die gesamte Datei auf den Server "hochgeladen" wurde. Sind alle Daten übertragen, wird die Datenverbindung wieder geschlossen. Natürlich möchten wir auch hier wieder während des Upload-Vorgangs den Fortschritt in Form einer Balkengrafik anzeigen. Ebenso soll es auch möglich sein, den Vorgang jederzeit abbrechen zu können.

' Datei "uploaden"
Friend Function UploadFile(ByVal LocalFile As String, _
  ByVal ServerFile As String, _
  Optional ByVal StartUploadAt As Long = 0)
 
  Dim TmpPort As Long
  Dim TmpPortStr As String
  Dim SendBuff As String
 
  ' Servermodus auf Binär stellen
  If SendCommand(OvermitBinary, CommandOk, CommandOk, _
    CommandFail) = False Then Exit Function
 
NewUniquePort:
  ' Port öffnen (für das Senden der Daten)
   TmpPort = 0
 
  ' Neuen Port ermitteln
  Call GetNewPort(TmpPort, TmpPortStr)
 
  ' Neuen Port öffnen
  With Downsock
    .Close
    .LocalPort = TmpPort
    .Listen
  End With
 
  ' neu geöffneten Port dem Server mitteilen
  If SendCommand(SetPort & TmpPortStr, CommandOk, CommandOk, _
    CommandFail, 0&, "Neuer Port geöffnet") = False Then
    Exit Function
  End If
 
  ' Upload-Startposition setzen
  SendCommand ResumeTransfere & StartUploadAt, _
    ResumingSupportet, CommandOk, CommandNotImplemented
 
  ' Progressbar einstellen
  ' siehe Workshop-Projekt
 
  ' lokale Datei öffnen
  FFile = FreeFile
  Open LocalFile For Binary As FFile
  Seek #FFile, StartUploadAt + 1
 
  ' Anfrage an Server senden
  TAbort = False
  TotalBytes = LOF(FFile)
  OvermittedBytes = StartUploadAt
  If SendCommand(Upload & ServerFile, TransferStart, _
    TransferStart, PermissionDenied) = False Then
 
    ' Zugriff verweigert (auf der Server-Seite)
    ...
    Exit Function
  End If
 
  ' Warten bis die Datenleitung verbunden ist
  Dim TimeOut As Long
  TimeOut = GetTickCount + 1000 * ConnectTimeOut
  Do
    DoEvents
  Loop Until Downsock.State = sckConnected Or _
    TimeOut < GetTickCount / 1000
 
  ' TimeOut überschritten!
  If Downsock.State <> sckConnected Then Exit Function
 
  ' Alle Daten senden und warten bis die Daten den
  ' Server erreichen
  PacketSend = True
  Do
    DoEvents
 
    ' Wenn vorheriges Päckchen beim Server ist,
    ' neues Daten-Päckchen senden
    If PacketSend = True And _
      OvermittedBytes <> TotalBytes Then
 
      ' Puffergröße festlegen
      If TotalBytes - OvermittedBytes < SendBufferLenght Then
        SendBuff = Space(TotalBytes - OvermittedBytes)
      Else
        SendBuff = Space(SendBufferLenght)
      End If
 
      ' Übertragene Bytes aufaddieren
      OvermittedBytes = OvermittedBytes + Len(SendBuff)
 
      ' Progressbar aktualisieren
      ShowProgress picProgress, OvermittedBytes, 0, TotalBytes
 
      ' Daten aus der Datei lesen
      Get #FFile, , SendBuff
 
      ' Daten an den Server schicken
      If TAbort = True Then Exit Do
      PacketSend = False
      Downsock.SendData SendBuff
    End If
  Loop Until TotalBytes = OvermittedBytes And PacketSend = True
 
  ' Socket schließen
  Downsock.Close
  SendCommand "", TransferComplete, TransferComplete, -1&
 
  ' Für den nächsten Down-/Upload zurücksetzen
  OvermittedBytes = 0
  TotalBytes = 0
 
  ' Datei schließen
  If FFile <> -1 Then
    Close FFile
    FFile = -1
  End If
 
  ' Falls abgebrochen wurde
  If TAbort = True Then
    ...
  End If
 
  ' Falls die Verbindung zur Datenleitung nicht
  ' aufgebaut werden konnte, nochmals versuchen
  If LastServerCmd = DataConnectionError Then GoTo NewUniquePort
End Function

Wie bereits schon bei der Download-Prozedur lässt sich auch bei ein abgebrochener Upload-Vorgang ab einer bestimmten Dateiposition fortsetzen. Hierzu muss einfach dem Parameter StartUploadAt die entsprechende Bytes-Position innerhalb der Datei mitgeteilt werden.

Immer wenn wir (besser gesagt das Winsock-Control - in unserem Fall das Downsock-Control) ein Datenpaket verschickt haben, wird das Ereignis SendComplete ausgelöst. Dies ist dann auch die "richtige Stelle", an der wir die Variable PaketSend auf True setzen, so dass sich im Anschluss daran, das nächste Datenpaket auf den Weg machen kann

' Wenn beim Upload die Daten gesendet sind,
' Variable auf True stellen
Private Sub DownSock_SendComplete()
  PacketSend = True
End Sub

Alle wichtigen Kommandos an den Server

Ein richtiger FTP-Client kann natürlich noch mehr, als nur Verzeichnisse anzeigen und Dateien up- und downzuloaden. Standard-Befehle, wie Dateien und Verzeichnisse löschen oder Dateien und Verzeichnisse umbenennen sollte demnach zur "Grundausstattung" gehören.

Alle diese Befehle sind FTP-Kommandos, welche an den Server geschickt werden. Hierbei handelt es sich um Strings (z.B. STOR - um Dateien zu senden), welche immer mit einem vbCrLf-Zeichen beendet werden müssen. Erwartet ein Kommando einen Parameter, wie z.B. den Verzeichnisnamen beim Wechseln des Verzeichnisses, so wird dieser Paramater getrennt durch ein Leerzeichen direkt hinter dem Kommando angegeben.

Nachfolgend eine Liste mit den wichtigsten FTP-Kommandos:

KommandoParameterBeschreibung
USERErwartet einen gültigen Benutzernamen oder "Anonymous" für die Anmeldung am ServerDieses Kommando wird direkt nach der Willkommensnachricht erwartet und teilt dem Server den Benutzernamen mit.
PASSErwartet ein Passwort. Gültige Werte sind "Pass", eine Email-Adresse oder zugelassene Passwörter für den BenutzernamenDieses Kommando teilt dem Server das Passwort mit.
QUITKein ParameterVerbindung zum Server trennen
PWDKein ParameterServer übermittelt das aktuelle Verzeichnis
LISTKein ParameterAnforderung der Verzeichnisstruktur des aktuellen Verzeichnisses
TYPE"A" für Ascii-Übertragungsmodus oder "I" für Binär-ÜbertragungsmodusFestlegen des Übertragungsmodus
PORTErwartet einen String zum Verbinden mit einem PortDer Server verbindet sich mit diesem Port - und zwar beim nächsten Up-/Download oder Übermitteln eines Verzeichnisses
CWDErwartet einen rekrusiven oder kompletten DateipfadDer Server wechselt in das im Parameter angegebene Verzeichnis
CDUPKein ParameterDer Server wechselt in das übergeordnete Verzeichnis
SIZEErwartet einen Dateinamen mit kompletten PfadangabenDer Server übermittelt die Dateigröße der angegeben Datei (in Bytes)
RESTErwartet eine DateipositionDer Server beginnt den nächsten Up-/Download an der angegebenen Dateiposition
RETRErwartet einen Dateinamen mit kompletten PfadangabenDer Server sendet die angegebene Datei über den zuvor definierten Datenport
ABORKein ParameterDer Server schliesst den aktuellen Datenport und beendet den laufenden Up-/Downloadprozess
STORErwartet einen Dateinamen mit kompletten PfadangabenDer Server öffnet den Datenport und speichert die ankommendenen Daten in die angegebene Datei
RNFRErwartet einen existierenden Dateinamen mit kompletten PfadangabenLegt eine Datei fest, die umbenannt oder verschoben werden soll (Rename From) und wartet anschliessend auf das Kommando RNTO
RNTOErwartet einen Dateinamen mit kompletten PfadangabenLegt den neuen Dateinamen fest (Rename To). Der Server benennt die zuvor über RFNR festgelegte Datei in den angegebenen Dateinamen um und/oder kopiert diese in das angegebene Verzeichnis
MKDErwartet vollständigen VerzeichnisnamenErstellt ein neues Verzeichnis
RMDErwartet einen existierenden Verzeichnisnamen mit vollständiger PfadangabeLöscht ein Verzeichnis (ACHTUNG: Das Verzeichnis kann nur gelöscht werden, wenn sich keine Dateien und/oder Ordner mehr in diesem befinden)
DELEErwartet einen existierenden Dateinamen mit vollständiger PfadangabeLöscht die im Parameter angegebene Datei

Alle wichtigen Server-Rückmeldungen

Nach dem Senden eines Kommandos an den Server (siehe Tabelle FTP-Kommandos) muss immer auf die Server-Anwort gewartet werden. Hierbei handelt es sich um eine dreistellige Zahl, die einen Status oder eine erwartete Aktion beschreibt. Serverkommandos sind nur abgeschlossen, wenn der Zahl ein Leerzeichen folgt. Abgeschlossen sind die Kommandos wieder durch ein vbCrLf-Zeichen.

Enthält die Server-Rückmeldung zusätzlicher Parameter, so sind diese durch ein Leerzeichen getrennt direkt hinter der dreistelligen Zahl angegeben.

KommandoParameterBeschreibung
150 Der Server hat sich erfolgreich mit dem Datenport verbunden
200 Ein Kommando wurde erfolgreich ausgeführt
213Dateigröße in BytesServer hat die Dateigröße übermittelt
220WillkommensnachrichtDer Server sendet dieses Kommando direkt nachdem eine Verbindung hergestellt wurde
226 Der Server hat alle Daten über den Datenport übertragen
230 Das Passwort wurde akzeptiert. Der Client ist nun erfolgreich eingeloggt.
231 Der Benutzername wurde akzeptiert und das Passwort wird anschliessend erwartet
250VerzeichnispfadEine Verzeichnisfunktion war erfolgreich
257DateipfadDateiaktion war erfolgreich
321 Das Passwort wurde nicht akzeptiert, die Verbindung wird hierbei nicht getrennt.
321 Der Benutzername wurde nicht akzeptiert, die Verbindung wird hierbei nicht getrennt
350 Das Fortsetzen eines Down-/Uploads wird unterstützt und beginnt an der übermittelten Position
421 Der Server hat nach einer zu langen Ruhephase die Verbindung getrennt
425 Der Server konnte sich nicht mit dem Datenport verbinden
426GrundDer Server hat aus irgendeinem Grund die Datenleitung getrennt
500GrundEin Kommando konnte nicht ausgeführt werden
501 Der Benutzer hat nicht die Rechte, um die Aktion auszuführen
504 Der Server "versteht" das angegebene Kommando nicht
530Grund für die ZugangsverweigerungAus einem bestimmten Grund wurde das "Einloggen" nicht genehmigt
550 Der Benutzer hat nicht die Rechte, um die Aktion auszuführen

Zusammenfassung

Wir hoffen Ihnen mit unserem FTP-Workshop einen Einblick in die Vorgehens- und Arbeitsweise eines FTP-Client Programms gegeben zu haben. Mit dem in den beiden Teilen vermittelten Wissen, Befehlen und Funktionen, sollten Sie nun in der Lage sein, Ihren eigenen FTP-Clienten zu programmieren. Einen Ansatz hierfür bekommen Sie, wenn Sie sich unser Demo-Projekt zum FTP-Workshop downloaden.

Themen aus Teil 1:

  • Anmelden und Verbinden mit dem FTP-Sever
  • Verzeichnisinformationen lesen und in einer Liste anzeigen
  • Wechseln in über- und untergeordnete Verzeichnisse und Inhalt anzeigen
  • Verbindung beenden

Themen aus Teil 2:

  • Download von Dateien
  • Upload von Dateien
  • Abbrechen und Fortsetzen eines Up-/Downloads
  • Wichtige Kommandos an den Server
  • Rückgabewerte vom Server

Hinweis zum Abschluss
Bitte beachten Sie, dass das Debugging des Projekts bei laufender Server-Verbindung und Daten-Übertragung sehr schwierig ist, da ankommende Serverdaten im "Speicher-Nirvana" landen, wenn sich der Debugger in der Ruhephase befindet!

Das Beispielsprojekt zum Teil 2

Das Beispielsprojekt zum Teil 2 des FTP-Workshops zeigt, wie man sich mit einem FTP-Server verbindet und sich dann innerhalb des Server-Verzeichnisses bewegen kann (also Verzeichnisse und Dateien anzeigen, inkl. Verzeichniswechsel). Zusätzlich lassen sich Dateien up-/ und downloaden.

Dieser Workshop wurde bereits 21.902 mal aufgerufen.

Über diesen Workshop im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Workshop, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (6 Beiträge)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Workshops finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2017 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel