User Tools

Site Tools


Sidebar

Network and communication

k24:k24.2:k24.2.3.1:start

24.2.3.1 Project 1 - FTP Client

The FTPClient (gb.net.curl) class provides an FTP client that allows downloading files from an FTP server, uploading files to an FTP server and sending FTP commands to an FTP server. This functionality should be demonstrated in the project. The programme interface represents on the one hand the view of a local directory and the files contained therein and on the other hand, among other things, of a remote directory and its files. A DirView and a FileView are used as controls for the local view. The remote directories on the FTP server are mapped to a TreeView. A GridView is used to display the file names (with matching icon) and selected file properties in a selected remote directory:

BILD
Figure 24.2.3.1.1: GUI - FTP Client Program1

The functionality of the FTP client can be described in a simplified way as follows:

PC: You can

  • create a directory (+), delete a directory (-),
  • delete a file (-) and
  • upload one or more selected files to the selected directory on the FTP server (↑).
  • Alternatively, you can upload one or more files to the selected directory on the FTP server using drag & drop!

FTP server: You can

  • create a directory (+), delete a directory (-),
  • rename a directory,
  • change step by step into the specified (base) directory (in the above case this is /html),
  • delete a file (-),
  • rename a file and
  • download one or more marked files to the selected local directory (↓).
  • Alternatively, you can download one or more files into the selected local directory using drag & drop!

For testing the programme, the FTP server vsFTPd was installed locally and configured appropriately. At https://gambas-buch.de/doku.php?id=k24:k24.15:start you will find a detailed description of the installation and configuration of the secure FTP server in a digression in chapter 24.15.

The idea for this Gambas project comes from Jorge Carrión (2013). However, he has further developed his programme on the basis of the class FTPClient with a different approach (GUI) and new emphases. You can now find Jorge's final project at https://gitlab.com/shordi/gbftp.

24.2.3.1.1 Note on FTP and FTPS

The class FTPClient (gb.net.curl) currently (23/03/2022) provides only unencrypted FTP and is therefore insecure! * Please switch to FTP over TLS (FTPS).

24.2.3.1.2 Connection data

The FTP connection details dialogue captures the URL of the FTP server, the FTP user name, its FTP password and the base path on the FTP server:

Login-Dialog
Figure 24.2.3.1.2: Dialog 1 - FTP connection data

24.2.3.1.3 Source code dialogue - FTP connection data

The dialogue for reading the FTP connection data is called up in the main programme and is pleasantly short:

' Gambas class file
 
' ● Unverschlüsseltes FTP ist unsicher. Bitte wechseln Sie zu FTP über TLS.
' ● Unencrypted FTP is insecure. Please switch to FTP over TLS.
 
Private cFTPAccountData As Collection
 
Public Sub _call(sTitel As String) As Collection
 
    Me.Text = sTitel
 
'-- Returns if one of the two buttons was clicked!
'-- The return value is set in the Me.Close() call and indicates whether the dialog was aborted or not.
    If Me.ShowModal() = 0 Then
       Return Null
    Else
       If txbFTPServerURL.Text And If txbFTPUserName.Text And If txbFTPUserPassword.Text And \
       If txbFTPServerInitialPath.Text Then
             cFTPAccountData = New Collection
             cFTPAccountData["FTPServerURL"] = txbFTPServerURL.Text
             cFTPAccountData["FTPUsername"] = txbFTPUserName.Text
             cFTPAccountData["FTPPassword"] = txbFTPUserPassword.Text
             If txbFTPServerInitialPath.Text Not Ends "/" Then txbFTPServerInitialPath.Text &= "/"
             cFTPAccountData["FTPServerInitialPath"] = txbFTPServerInitialPath.Text
             Return cFTPAccountData
       Else
          Message.Error(("The FTP account data are not complete!"))
          Return Null
       Endif
    Endif
 
End
 
Public Sub Form_Open()
  txbFTPServerURL.Text = MSettings.AppSettings["FTP/ServerURL"]
  txbFTPUserName.Text = MSettings.AppSettings["FTP/Username"]
  txbFTPUserPassword.Text = MSettings.AppSettings["FTP/Password"]
  txbFTPServerInitialPath.Text = MSettings.AppSettings["FTP/InitialPath"]
End
 
Public Sub bConnect_Click()
    Me.Close(1)
End
 
Public Sub bCancel_Click()
    Me.Close(0)
End
 
Public Sub Form_Close()
    If rbtnRemember.Value = True Then
       MSettings.AppSettings["FTP/ServerURL"] = txbFTPServerURL.Text
       MSettings.AppSettings["FTP/Username"] = txbFTPUserName.Text
       MSettings.AppSettings["FTP/Password"] = txbFTPUserPassword.Text
       If txbFTPServerInitialPath.Text Not Ends "/" Then txbFTPServerInitialPath.Text &= "/"
       MSettings.AppSettings["FTP/InitialPath"] = txbFTPServerInitialPath.Text
    Else
       MSettings.AppSettings["FTP/ServerURL"] = ""
       MSettings.AppSettings["FTP/Username"] = ""
       MSettings.AppSettings["FTP/Password"] = ""
       MSettings.AppSettings["FTP/InitialPath"] = ""
    Endif
    MSettings.AppSettings.Save()
End

24.2.3.1.4 Program - FTPCLIENT

The programme source code is given only in selected sections and is sufficiently commented there. The complete project archive can be found in the download area.

It has proved very helpful during programme development to use the debug property

'-- OPTION
   hFTPClient.Debug = True

to the value True.

24.2.3.1.5 Source code: Display of directories and files on the FTP server

The following three procedures realise the display of relevant directories and file names (with matching symbol) as well as selected file properties (→ Figure 24.2.3.1.1):

Public Sub GetServerDirectories()
 
    Dim n As Integer
    Dim sLine, sSize, sDate, sFileName As String
    Dim asDirRawData As New String[]
    Dim asDirData As New String[]
 
    asServerDirData = New String[]
    avServerFileData = New Variant[]
    aoFileIcon = New Object[]
 
    Inc Application.Busy
      hFTPClient.Async = False
      hFTPClient.URL = sFTPServerURL &/ sFTPServerInitialPath &/ txbServerDir.Text &/ "/"
 
  '-- Reads the contents of the specified server directory and stores it in a temporary file
      hFTPClient.Get(sTempFileName)
 
      If hFTPClient.ErrorText Then
         Message.Error(("The server reports the error") & ":\n" & hFTPClient.ErrorText)
     '-- The main program is terminated without comment!
         FMain.Close()
      Endif
 
      asDirRawData = Split(File.Load(sTempFileName), gb.NewLine, "\\", True)
 
      For Each sLine In asDirRawData
    '-- Several contiguous spaces in the string are reduced to 1 space character
        While InStr(sLine, "  ")
          sLine = Replace(sLine, "  ", " ")
        Wend
 
    '-- Last parameter avoid empty items on asDirData
        asDirData = Split(sline, " ", "", True)
 
    '-- . and .. are the convention names of actual and parent Directory we avoid them if exist
        If asDirData[8] = "." Or If asDirData[8] = ".." Then Continue
 
        sFilename = ""
    '-- Element 8 is only the *first* word of the name. There can also be more ...
        For n = 8 To asDirData.Max
          sFileName &= asDirData[n] & " "
        Next
    '-- Delete the last space added in the last for-next loop.
        sFileName = Left(sFileName, -1)
 
        If asDirData[0] Begins "d" Then  ' ◀—— The rights string for a directory begins with `d`
       '-- Add-Option: asDirData[8], we use the local variable `sFilename` instead
           asServerDirData.Add(sFilename)
        Else
           sSize = GetFileSize(CLong(asDirData[4]))                         ' ◀——  File-Size
           sDate = asDirData[6] & " " & asDirData[5] & " " & asDirData[7]   ' ◀——  Day - Month - Time
       '-- Filename, Filesize and Date of last change
           avServerFileData.Add([sFileName, sSize, sDate])
 
       '-- Returns the icon associated with a specific file. (DesktopMime class)
           File.Save("/tmp" &/ "t." & File.Ext(sFileName), "")
           aoFileIcon.Add(Desktop.GetFileIcon("/tmp" &/ "t." & File.Ext(sFileName), 16)) ' ◀——  File-Icon
 
        Endif
      Next
    Dec Application.Busy
 
End
Public Sub ShowServerDirectories()
 
    Dim sServerDirName As String
 
    For Each sServerDirName In asServerDirData
  '-- sServerDirName = Conv$(sServerDirName, "ISO-8859-15", "UTF-8") ' —▶ After a tip from Claus D.
      If trvServerDirectories.MoveTo(txbServerDir.Text &/ sServerDirName) Then
         trvServerDirectories.Add(txbServerDir.Text &/ sServerDirName, sServerDirName, \
                                  Stock["directory"], txbServerDir.Text, Null).EnsureVisible
      Endif
    Next
 
End
Public Sub ShowServerFiles()
 
    Dim iRow, iColumn As Integer
    Dim avLines As New Variant[]
 
    grvServerFiles.Rows.Count = avServerFileData.Count
 
    For iRow = 0 To avServerFileData.Max
      avLines = avServerFileData[iRow]
      grvServerFiles[iRow, 0].Picture = aoFileIcon[iRow]
      For iColumn = 0 To avLines.Max
    '-- grvServerFiles[iRow, iColumn].Text = Conv$(avLines[iColumn], "ISO-8859-15", "UTF-8")
        grvServerFiles[iRow, iColumn].Text = avLines[iColumn]
      Next
    Next
 
End
 
Public Sub trvServerDirectories_Click()
 
    txbServerDir.Text = trvServerDirectories.Key
    trvServerDirectories[trvServerDirectories.Key].Expanded = IIf(trvServerDirectories.Key = "/", \
    True, Not trvServerDirectories[trvServerDirectories.Key].Expanded)
 
    txbServerDir_Activate()
 
End

Note:\ For sorting the files on the FTP server, the following applies: first numbers, then upper case letters and then lower case letters (→ Figure 24.2.3.1.1).

24.2.3.1.6 Source text: File download

Whether you want to download only one file or several marked files from the FTP server to a marked local directory or you realise the download with Drog&Drop - you always use the following procedure RunDownload():

Private Sub RunDownload()
 
    Dim sServerFileName, sServerFilePath As String
    Dim aiRows As New Integer[]
    Dim n, iIndex As Integer
 
    If grvServerFiles.Rows.Selection.Count = 0 Then
       Message.Info(("No file was selected!"))
       Return
    Endif
 
    pbarDownload.Visible = True
    pbarDownload.Value = 0
 
    Inc Application.Busy
 
      aiRows = grvServerFiles.Rows.Selection
 
      For n = 0 To aiRows.Max
        pbarDownload.Value = 0
 
        iIndex = aiRows[n]
        sServerFileName = grvServerFiles[iIndex, 0].Text
        lblDownloadFilename.Text = " —▶ " & sServerFileName
 
        hFTPClient.Async = True
        hFTPClient.URL = sFTPServerURL &/ sFTPServerInitialPath &/ txbServerDir.Text &/ sServerFileName
        sServerFilePath = txbLocalDir.Text &/ sServerFileName
 
        hFTPClient.Get(sServerFilePath) ' ◀——  File-Download
 
        While hFTPClient.Status > 0
          If hFTPClient.TotalDownloaded > 0 Then
             pbarDownload.Value = hFTPClient.Downloaded / hFTPClient.TotalDownloaded
          Endif
          Wait 0.01
        Wend
 
        If hFTPClient.ErrorText Then
           Message(("The server reports the error") & ":\n" & hFTPClient.ErrorText)
        Else
           pbarDownload.Value = 1
           Wait 0.5
           dirvLocalDirectories.Reload()
        Endif
      Next
    Dec Application.Busy
 
End

24.2.3.1.7 Source code: File upload

Whether you want to upload only one file or several marked files from a local directory to a marked directory on the FTP server or implement the upload with Drog&Drop - you always use the following procedure RunUpload():

Private Sub RunUpload()
 
    Dim sLocalFileName, sLocalFilePath As String
 
    If filevLocalFiles.Selection.Count = 0 Then
       Message.Info(("No file was selected!"))
       Return
    Endif
 
    pbarUpload.Visible = True
    pbarUpload.Value = 0
 
    Inc Application.Busy
      For Each sLocalFileName In filevLocalFiles.Selection
        pbarUpload.Value = 0
 
        lblUploadFilename.Text = " —▶ " & sLocalFileName
 
    '-- Here it is possible to give the file to be uploaded a different name.
    '-- This is unnecessary, however, as files can be renamed on the server.
        hFTPClient.Async = True
    '-- Currently the file name is kept when uploading to the server
        hFTPClient.URL = sFTPServerURL &/ sFTPServerInitialPath &/ txbServerDir.Text &/ sLocalFileName
        sLocalFilePath = filevLocalFiles.Dir &/ sLocalFileName
 
        hFTPClient.Put(sLocalFilePath) ' ◀——  File-Upload
 
        While hFTPClient.Status > 0
          If hFTPClient.TotalUploaded > 0 Then
             pbarUpload.Value = hFTPClient.Uploaded / hFTPClient.TotalUploaded
          Endif
          Wait 0.01
        Wend
 
        If hFTPClient.ErrorText Then
           Message(("The server reports the error") & ":\n" & hFTPClient.ErrorText)
        Else
           pbarUpload.Value = 1
           Wait 0.5
           RefreshServerView()
        Endif
      Next
    Dec Application.Busy
 
End

Download

Project

Download

The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k24/k24.2/k24.2.3.1/start.txt · Last modified: 16.08.2022 (external edit)

Page Tools