User Tools

Site Tools


Sidebar

Network and communication

k24:k24.2:k24.2.3:start

24.2.3.0 Class FTPClient (gb.net.curl)

Note: FTP or “File Transfer Protocol” is an insecure protocol for transferring files between two systems and should only be used in limited circumstances or on networks you trust.

The class provides an FTP client that allows you to download files from an FTP server, upload files to an FTP server and send FTP commands to an FTP server. The class is based on the (base) class Curl in gb.net.curl.

To create a new FTP client:

Dim hFTPClient As FTPClient
hFTPClient = New FTPClient() As hFTPClient ' Event-Name

24.2.3.0.1 Properties

The FTPClient class has these properties:

PropertyData typeDescription
AsyncBooleanReturns the value or specifies whether the FTP request will be asynchronous. Requests are asynchronous by default!
BlockingBooleanReturns the value or specifies whether the stream is blocked. If this property is set, reading from the stream is blocked if there is nothing to read. Writing to the stream is blocked if, for example, the internal system buffer is full.
BufferSizeIntegerReturns or sets the preferred receive buffer size between 0 and 512 KB. If the buffer is set to zero, then the receive buffer size will have its default value, which is 16 KB according to the libcurl documentation.
ByteOrderIntegerReturns or sets the byte order used to read or write binary data to the data stream. The property can have the following values: gb.BigEndian or gb.LittleEndian.
DebugBooleanReturns or sets the debugging mode. For example, if the property is set to True, an FTPClient object prints all commands sent to the FTP server to the console (of the IDE).
DownloadedLongReturns the number of bytes already downloaded from the FTP server. The property can only be read.
TotalDownloadedLongReturns the total number of bytes expected to be downloaded. The property can only be read.
UploadedLongReturns the number of bytes that have already been uploaded. The property can only be read.
TotalUploadedLongReturns the total number of bytes expected to be uploaded. The property can only be read.
UserStringReturns or sets the FTP user name used for authorisation.
PasswordStringReturns or sets the FTP password used for authorisation.
EndOfFileBooleanThis property signals whether the end of the file was reached with the last use of LINE INPUT instead of reading an entire line with an end-of-line character. To check whether the end of file has been reached in any context, use the EOF function or the EOF property.
EndOfLineIntegerReturns or sets the line break separator used by the current stream. The possible values are: gb.Unix for lines separated by Chr$(10), gb.Windows for lines separated by Chr$(13) & Chr$(10) or gb.Mac for lines separated by Chr$(13). The value of this property is used by LINE INPUT, PRINT and the Stream.Lines property. In fact, gb.Unix allows you to read both Unix and Windows line formats. But it only writes the Unix format!
EofBooleanReturns True when a stream has reached its end. This is an equivalent of the EOF function.
LinesStream.LinesReturns a (virtual) object with which you can enumerate and evaluate a data stream line by line.
TimeoutIntegerReturns or sets the client timeout in seconds. The connection from the client to the FTP server is aborted if it takes more than the specified number of seconds. If the timeout is zero, no timeout is defined. Do not forget to set this property if it is a synchronous request, otherwise the FTP client can wait forever for the connection to the FTP server to be established!
URLStringReturns or sets the URL of the resource to be downloaded.
ProxyCurl.Proxy Returns a (virtual) object used to define proxy parameters (Auth, Host, Password, Type, User). If no proxy is defined, the default proxy is used.
NoEPSV BooleanReturns the value whether the FTP Client can use EPSV for passive FTP downloads or not, or you set the value. If this property is set, EPSV is not used, only PASV. By default, this property is not set and EPSV is always allowed. If the FTP server is an IPv6 host, setting this property has no effect.
TargetFileStringReturns the target file used only for download operations or sets the path for the target file.
TagVariantReturns or sets the tag property associated with the stream. This property is intended for the programmer and is never used by the component. It can take any Variant value.
StatusIntegerReturns the status of the FTP client. It can take three values.
SSLCurl.SSLThis (virtual) property allows to define the SSL properties of the underlying CURL connection with the two properties VerifyHost (default) and VerifyPeer.
HandleIntegerReturns the system file descriptor associated with this stream.
IsTerm BooleanReturns True if a stream is associated with a terminal.
TermStream.TermReturns a (virtual) object that allows the management of the terminal associated with the stream.
ErrorTextStringReturns the error string associated with the error code returned by the curl library. If the status has a positive value, then an empty string is returned.

Table 24.2.3.0.1 : Properties of the FTPClient class

Example of Lines property:

Dim hFile As File
Dim sLine As String

hFile = Open "/var/log/syslog"
For Each sLine In hFile.Lines
  If InStr(sLine, "[drm]") Then Print sLine
Next

Status property values that can only be read:

Net.Inactive        (0)	Der FTP-Client ist inaktiv.
Net.ReceivingData   (4)	Der FTP-Client empfängt Daten aus dem Netzwerk.
Net.Connecting      (6)	Der FTP-Client verbindet sich mit dem FTP-Server.

If an error occurred, then the status value is negative. The status value is actually -1000 minus the libcurl error code. Most of these error codes have a corresponding constant in the Net class. To know exactly what an error code means, you need to look at the libcurl error code list at https://curl.se/libcurl/c/libcurl-errors.html or at the Gambas Club at https://www.gambas-club.de/viewtopic.php?f=3&t=5580&p=13190&hilit=Curl+error#p13190.

FTPClient has two ways to work depending on the Async property. If Async has the value TRUE, then the programme stops until the requested operation is completed. This guarantees that the desired result is completed before the programme continues. However, you will not receive any information while the process is running. If the property has the value FALSE, the programme requests the FTP operation from the server and continues. In this case, you can access the status of the process.

For programme development, it is advantageous to set the debug property to True. Then you will always see the complete connection log in the console of the IDE - as in the following example:

*   Trying 109.xyz.140.40:21...
* TCP_NODELAY set
* Connected to gambas-buch.de (109.xyz.140.40) port 21 (#0)
< 220 FTP Server ready.
> USER ftp_username
< 331 Password required for ftp_username
> PASS ftp_password
< 230 Zugriff gewaehrt fuer ftp_username
> PWD
< 257 "/" is the current directory
* Entry path is '/'
> CWD base
* ftp_perform ends with SECONDARY: 0
< 250 CWD command successful
> CWD dwiki
< 250 CWD command successful
> CWD data
< 250 CWD command successful
> CWD k3
< 250 CWD command successful
> CWD k3.1
< 250 CWD command successful
> EPSV
* Connect data stream passively
< 229 Entering Extended Passive Mode (|||65089|)
*   Trying 109.xyz.140.40:65089...
* TCP_NODELAY set
* Connecting to 109.xyz.140.40 (109.xyz.140.40) port 65089
* Connected to gambas-buch.de (109.xyz.140.40) port 21 (#0)
> TYPE I
< 200 Type set to I
> STOR start.txt
< 150 Opening BINARY mode data connection for start.txt
* We are completely uploaded and fine
* Remembering we are in dir "base/dwiki/data/k3/k3.1/"
< 226 Transfer complete
* Connection #0 to host gambas-buch.de left intact

24.2.3.0.2 Methods

The FTPClient class has the following methods:

MethodReturnTypeDescription
Begin( )-Begin buffering the data written to the stream so that everything is sent at once when the Send method is called.
Send( )-All data is sent at once since the last call of the 'Begin' method.
Stop( )-Cancels the current command.
Peek( )StringReturns the contents of the internal stream buffer. The data is not removed from the buffer so that it is available for the next read.
Watch( Mode As Integer, Watch As Boolean )-Start or stop monitoring the stream file descriptor for reading or writing after it has been opened. Mode is the monitoring type: (1) gb.Read to watch while reading and (2) gb.Write to watch while writing. Set Watch to TRUE to enable monitoring or False to disable it.
Close( )-Closes the stream.
ReadLine([ Escape As String ])StringRead a line of text from the stream, as with the LINE INPUT statement. If the optional parameter 'Escape' is specified, then line breaks between two escape characters are ignored. This method is very useful when reading CSV files.
Get([ TargetFile As String ])-Loads a file from the FTP server. If the TargetFile property is specified, the file is automatically saved in the path of TargetFile. Before using this method, you must fill the URL property with the desired hostname and the path to the document to be retrieved.
Put( LocalFile As String )-Send a file to the FTP server. The parameter LocalFile contains the path of the file to be sent from the FTP client system.
Exec( Commands As String[] )-Executes certain FTP commands directly. The parameter 'Commands' is a string array in which each element represents a single FTP command.

Table 24.2.3.0.2 : Methods of the FTPClient class

24.2.3.0.3 Events

The FTPClient class has 6 events:

MethodDescription
Connect()The event is triggered when a connection is established from the FTP Client to the FTP Server.
Read()The event is triggered when (user) data is received.
Progress()This event is triggered periodically as long as something is being downloaded or uploaded (user data, FTP commands, receipts, error messages).
Finished()This event is triggered when a download or upload is finished without error.
Error()The event is triggered when an error (from the CURL library) is returned.
Cancel()This event is triggered when a request has been cancelled.

Table 24.2.3.0.3 : Events of the FTPClient class

24.2.3.0.4 Examples

Example 1: Put() method (upload).

The following source code excerpt is from a program for inserting individual pages in DokuWiki format into the Gambas book on gambas-buch.de:

Public hFTPClient As FtpClient
 
Public Sub Form_Open()
 
    MAdditional.CheckNetwork()
 
    hFTPClient = New FtpClient As "hFTPClient"
 
    hFTPClient.User = "ftp123"
    hFTPClient.Password = "pass456"
 
...
 
End
 
Public Sub btnFileUpLoad_Click()
 
    Dim bFTPClientStatus As Boolean = False
 
    FileUpload()
 
    Repeat
      Wait 0.001
      lblFTPStatus.Text = "FTP-Status = " & hFTPClient.Status
    Until bFTPClientStatus = bConnected
 
End
 
Public Sub hFTPClient_Connect()
    lblFTPStatus.Text = "FTP status: Connection to FTP server established!"
    bConnected = True
End
 
Public Sub hFTPClient_Finished()
 
    ProgressBar1.Value = 1
    btnFileUpLoad.Picture = Picture["leds/led_green_16x16.png"]
    lblFTPStatus.Text = "FTP status: Transfer complete"
 
    If bConnected = True Then hFTPClient.Close()
 
End
 
Public Sub hFTPClient_Progress()
 
'-- (Relative) Display of the uploaded bytes in relation to the size of the transferred file.
    If hFTPClient.TotalUploaded > 0 Then
       ProgressBar1.Value = hFTPClient.Uploaded / hFTPclient.TotalUploaded
    Endif
 
End
 
Public Sub hFTPClient_Error()
  Message.Error("<b><font color='DarkRed'>FTP:  ERROR</b></font><hr>" & hFTPClient.ErrorText)
End
 
Private Sub FileUpload()
 
    hFTPClient.URL = txbTargetURL.Text
'-- The Argument in the Put(sArg) method is the path of the file to be uploaded *on the local PC*
'-- Upload the selected DokuWiki source text file:
    hFTPClient.Put(txbSourcePath.Text)
 
End

B1
Figure 24.2.3.0.1: The upload of a file was successful.

Note:The names of the LocalSource file and the target file do not necessarily have to be the same! This applies to the upload as well as to the download!

Errors during the upload of individual pages are intercepted and displayed by the programme:

B2
Figure 24.2.3.0.2: Upload errors

Example 2: Get() method (download)

This example was chosen because it presents a special feature. Normally, you specify as an argument to the Get() method a complete path for the file on the FTP server to be downloaded from the FTP server to a selected directory on the FTP client system. However, if you specify a complete path for a directory on the FTP server - which must end with / - then the contents of that directory will be returned:

B3
Figure 24.2.3.0.3: Contents of a selected directory on the FTP server.

The source code for reading the contents of a selected directory on the FTP server is pleasantly short and is therefore given in full. You can test the project yourself, as the FTP account data for the public FTP server are also given:

' Gambas class file
 
Public hFTPClient As FtpClient
 
Public Sub Form_Open()
 
    FMain.Caption = "FTP-Server: Directory List"
 
    hFTPClient = New FtpClient As "hFTPClient"
 
    hFTPClient.User = "anonymous"      '-- Required: `anonymous`
    hFTPClient.Password = "wer@ist.da" '-- Required: An arbitrary, but syntactically correct email address
 
    hFTPClient.Debug = True
 
End
 
Public Sub hFTPClient_Error()
    txaOutput.Insert("FTP-Error-Text => " & hFTPClient.ErrorText & gb.NewLine)
    txaOutput.Insert("FTP Status: " & hFTPClient.Status & gb.NewLine)
End
 
Public Sub btnGetList_Click()
 
    Dim aList As String[]
    Dim iCount As Integer
 
    aList = GetList("ftp.uni-erlangen.de/pub/")
'-- aList = GetList("ftp.uni-erlangen.de/pub/ubuntu/")
 
    txaOutput.Clear()
 
    For iCount = 0 To aList.Max
      If iCount < aList.Max Then
         txaOutput.Insert(aList[iCount] & gb.NewLine)
      Else
         txaOutput.Insert(aList[iCount])
      Endif
    Next
 
End
 
Private Function GetList(argURL As String) As String[]
 
    Dim sTempFileName As String = Temp()
    Dim aList As String[]
 
    hFTPClient.URL = argURL
    hFTPClient.Async = False
    hFTPClient.Timeout = 3
 
    hFTPClient.Get(sTempFileName)
 
    aList = Split(File.Load(sTempFileName), gb.NewLine)
 
    Return aList
 
End

The main load is borne by the function GetList(argURL). A temporary file is used as the (download) file, as its content is of interest, which is stored in the return value of the function.

Example 3: Exec() method

In practical work, the Exec() method has proved useful for creating and deleting a directory on the FTP server, among other things:

  Inc Application.Busy
    hFTPClient.Async = False
    hFTPClient.Exec(["MKD " & "BaseDirectoryPath/DirectoryName_Create"])
  Dec Application.Busy
  Inc Application.Busy
    hFTPClient.Async = False
    hFTPClient.Exec(["RMD " & "BaseDirectoryPath/DirectoryName_Delete"])
  Dec Application.Busy

The following source code section provides an overview of all FTP commands implemented on the FTP server. Take into account that the output is only displayed in the console of the IDE if the debug property has the value True:

  hFTPClient = New FtpClient As "hFTPClient"
 
  hFTPClient.User = "ftp123"
  hFTPClient.Password = "pass345"
  hFTPClient.URL = "gambas-buch.de"
  hFTPClient.Async = False
  hFTPClient.Timeout = 3
 
  hFTPClient.Debug = True
  hFTPClient.Exec(["HELP"])

This is the output for the FTP server (vsFTPd) used by the author:

> HELP
* ftp_perform ends with SECONDARY: 0
< 214-The following commands are recognized (* =>'s unimplemented):
<  CWD     XCWD    CDUP    XCUP    SMNT*   QUIT    PORT    PASV
<  EPRT    EPSV    ALLO*   RNFR    RNTO    DELE    MDTM    RMD
<  XRMD    MKD     XMKD    PWD     XPWD    SIZE    SYST    HELP
<  NOOP    FEAT    OPTS    HOST    CLNT    AUTH    CCC*    CONF*
<  ENC*    MIC*    PBSZ    PROT    TYPE    STRU    MODE    RETR
<  STOR    STOU    APPE    REST    ABOR    USER    PASS    ACCT*
<  REIN*   LIST    NLST    STAT    SITE    MLSD    MLST

Delete a single file on the FTP server like this:

  Inc Application.Busy
    hFTPClient.Async = False
    hFTPClient.Exec(["DELE " & "BaseDirectoryPath/FileName"])
  Dec Application.Busy
 
  If hFTPClient.ErrorText Then
     Message.Error("ERROR:<br>" & hFTPClient.ErrorText)
  Endif

24.2.3.0.5 FTP Accounts

It is a good idea to provide the required FTP account data for an FTP programme either through a single dialogue or through an FTP account manager with several dialogues. Suggestions for suitable dialogues or for account managers can already be found in the Gambas book:

https://gambas-buch.de/doku.php?id=k12:k12.4:k12.4.4:k12.4.4.1:start
https://gambas-buch.de/doku.php?id=k24:k24.3:k24.3.4:start

B4
Figure 24.2.3.0.4: Account dialogue for an FTP server

If you use multiple FTP servers, then an FTP account manager will be the right choice:

B5
Figure 24.2.3.0.5: FTP account manager

24.2.3.0.6 Digression: Using the command line tool Curl with FTP, SFTP and FTPS

A short introduction to the use of Curl, reduced to the essentials, can be found on this website (as of 24.01.2022):

http://www.mukeshkumar.net/articles/curl/how-to-use-curl-command-line-tool-with-ftp-and-sftp

24.2.3.0.7 Project FTP Client

In the next chapter, you will be introduced to a project for an FTP Client based on the class FTPClient.

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/start.txt · Last modified: 16.08.2022 (external edit)

Page Tools