Internet - File Transfers
In this tutorial I will cover how to perform file transfers between your
PC and a web server. The topics of web site management, dynamic
generation of web pages, and control/script inclusion in web pages is
covered in a different tutorial.
In the Professional and Enterprise Editions of VB are the two controls which
provide Internet features - the Internet Transfer Control and the Web Browser
Control. The Internet Transfer Control (ITC) provides both FTP and HTTP file
transfer controls and is the subject of this tutorial - as is the use of
the wininet.dll, which also provides file transfer capabilities that you
can access from within your VB applications.
The wininet.dll file is simply a library of functions that you can use
to do file transfers. It is not a part of VB6, but is installed
along with the Microsoft Internet Explorer. This means you can safely
assume that it is available on most PCs.
The reason for using the ITC is simplicity. The control provides a very
straightforward, fairly simple interface to use in your VB programs. The
down side is that the control is about 126K in size, increasing the
size of the installation files your application users will have to download.
By using the existing wininet.dll file, you eliminate the increased
application distribution file size, plus the wininet.dll offers greater
control over the file transfer process. As you would expect, the wininet.dll
is harder to learn and is not documented as part of the VB documentation
So, I'll focus first on the ITC, then end with enough detail on wininet.dll
to show you how to use it as an alternative to the ITC.
For our purposes, only two of the many protocols matter - HTTP and FTP. Protocols
are simply rules which programmers have agreed upon, and documented so that
anyone using the protocol can be assured that their software can communicate
with other programs which also use that protocol.
For the purposes of file transfer as discussed in this tutorial,
It's not really that important to understand the details of either protocol,
but there are a few facts which are important to know. The key point to
remember right now is that the code for using the ITC for an FTP or for an
HTTP file transfer are slightly different.
Most web sites are accessible by both FTP and HTTP (i.e., servers typically
run both FTP and HTTP server software for accessing content), so you can
usually chose which approach to take.
In general, it really makes little difference which protocol you use. Many
of the books I've read recommend the FTP protocol because it is more flexible
than HTTP (i.e., read that as FTP has more features which can be controlled
by code than does HTTP). I generally agree with that recommendation, but will
confess that my own freeware applications now have an online update feature
which is based on the HTTP protocol.
Here's the tradeoff that drove me to that decision:
- FTP - Many ISPs do not allow anonymous (i.e., no username and no
password) FTP connections to a website. But, I do not want to put my
username/password into a distributed application for fear of compromising
security on my web site. I could password protect and expose just a particular
directory on the web site, but I've chosen to take no risks in that area.
- HTTP - The ITC code for an HTTP file transfer is extremly simple (the
FTP code is not that complicated, it's just that the HTTP code is simpler).
One of the key drawbacks of using the ITC for file transfer (regardless of
the protocol that is used) is that it does not provide any built-in
capability to identify how many bytes of the transfer are complete at any
point in time. All you can tell from within your VB program is whether
the file transfer is in progress, or that it has stopped (because of a
successful transfer or some error that stopped the file transfer process).
This is one of the key reasons you might be interested in looking at one of
the 3rd party file transfer OCXs.
OpenURL Method of File Transfer
Now that I've gotten the introductory comments out of the way, let's talk
about the details of the ITC. The two most important things to know about
the ITC is that there are two methods of downloading files from a web
site - the OpenURL method and the Execute method. Both support the FTP and
HTTP file transfer protocols.
The OpenURL method is very simple. You put in a file name to download
and tell the program whether the file is all text or binary. The code
looks for an HTTP transfer of a text file looks like this:
text1.text = inet1.OpenURL ("http://www.vbinformation.com/badclick.htm", icString)
The code for an HTTP transfer of a binary file looks like this:
Dim bData() as Byte
bData() = inet1.OpenURL ("http://www.vbinformation.com/badclick.htm", icByteArray)
Since all files (text or binary) can be transferred as a binary file, I used
the same file name in both examples. Note that in the first case, the
downloaded file content is placed in a textbox named 'text1'. In the second
case, the downloaded file content is saved in a Byte array whose upper bound
is set by the number of bytes downloaded by the OpenURL method. Also, note
that both examples use HTTP URLs, but FTP URLs could have been used just
In case you don't remember, an easy way to save the bData byte array is:
Open "filename" for Binary as #1
Put #1, , bData()
This is really all there is to successfully downloading a file by using the
OpenURL method. I'll cover the question of errors (such as when the server
is down, or the file is not there) later in this tutorial.
You should note that the OpenURL method is synchronous - which simply means
that any code that follows the OpenURL statement will not be executed until
the file transfer is completed, or until the file transfer is stopped by
the occurence of an error or by a user command (I'll show how to do this
Execute Method of File Transfer
The second method for downloading a file is the Execute method. As you'll
see it provides more features, but is definitely more complicated to code.
The one key difference that you'll want to be aware of is that with the
Execute method the bytes of data are sometimes, but not always, kept within
the ITC itself (in a memory buffer). When the ITC does keep the downloaded
bytes in its buffer, you must use another method called
GetChunk to extract the dowloaded bytes. Whether the memory buffer is used
varies with the arguments used in calling the Execute method. I'll give more
detail on that later.
Another key difference that you should know about is the Execute method
is asynchronous - meaning that it will download the file in the background
and that any code following the Execute statement will be executed
Finally, to complicate the discussion a bit more, the arguments you use
in the Execute method differ depending on whether you want to use FTP or
HTTP for the file transfer.
Here's the general syntax for the Execute
inet1.Execute (url, operation, data, requestheaders)
For an FTP file transfer, only the first two arguments are used. For an HTTP
file transfer, all four arguments may be used.
Here's an example of the code you would use to start a transfer using
the Execute method and the FTP protocol:
inet1.Execute ("ftp://www.microsoft.com", "DIR")
This command transfers the directory listing of the Microsoft ftp site. Note
than while the OpenURL method returns data to a variable or an array, the
Execute method does not! The data returned by the Execute method will either
be kept within the ITC's buffer, or be directed to a file according to the
specifics of the command it is given.
The Execute method actually supports 14 FTP commands (which are placed in
the 'operation' argument), but there are primarily three (CD, GET, and PUT)
which you will use most often:
The first of these three allow you to make the connection to the FTP server
and to navigate to the directory where the files are located. The second
shows how to GET a file from the server and put it on your PC, while the
third shows how to PUT a local file from your PC onto the FTP server (in the
directory to which you navigated to using the CD command).
- inet1.Execute ("ftp://www.microsoft.com", "CD newdirectory"
- inet1.Execute ("ftp://www.microsoft.com", "GET remotefile localfile"
- inet1.Execute ("ftp://www.microsoft.com", "PUT localfile remotefile"
Also, you will note that the GET and PUT commands create a file on either
the local or remote computers. In these cases, the ITC memory buffer is not
used. However, the ITC memory buffer must be accessed in order to get the
output of the 'DIR' command.
In order to discuss how the ITC memory buffer is accessed, we have to
talk first about the StateChanged Event. Statechanged is the
only event the ITC control has, and it provides a variable called 'State'
which must be read to determine the status of a pending Execute method.
The State values are:
- icNone (0)
- icHostResolvingHost (1)
- icHostResolved (2)
- icConnecting (3)
- icConnected (4)
- icRequesting (5)
- icRequestSent (6)
- icReceivingResponse (7)
- icResponseReceived (8)
- icDisconnecting (9)
- icDisconnected (10)
- icError (11)
- icResponseCompleted (12)
Typically, Select Case code is used within the StateChanged event to
determine what action to take. In general, only actions 8, 11, and 12
are used to generate a code response. The others are used mostly to
decide what message to display in a status label/toolbar.
For State=12, where the file transfer is complete, the action you take is
entirely up to you. This would usually be a simple popup message telling
the user that the file transfer is complete.
For State=11, which indicates that an error has occurred, you would have
to generate code necessary to correct or ignore the error condition.
Generally, you simply wait for State=12 to indicate that the transfer is
complete. But, in some cases you may want to begin extracting data before
the transfer is complete. For example, the HTTP header information is
received first, but is not included in the ITC download buffer. To get that
information you use the .GetHeader method. You can use the State=8 to
determine when the header information is available.
In those cases where the ITC buffer is used to temporarily store the
downloaded information, the .GetChunk method is used. Here's the code for
the case where string data is being downloaded and a State=12 has been
received to indicate that the transfer is complete:
bData = inet1.GetChunk (1024, icString)
AllData = AllData & bData
Loop Until bData = ""
In the case where a State=8 has been received, it is possible that no actual
data is in the ITC buffer (such as when only header information has been
received). So, if the above code is used following a State=8 event, the
condition of bData="" may not indicate completion of the data transfer.
Finally, remember that you may have to set the .UserName and .Password
properties if you are using the FTP commands within the Execute method.
If the FTP site you are accessing allows 'anonymous' logon's, then you
will not have to set these properties.
As you saw in the sample code, the basics of file transfer don't require
knowledge of all 19 properties, 5 methods, and one event exposed
by the ITC. The following table list all of the ITC interface elements,
but as you will see in the discussion that follows, you will not use but
a few of these in most applications:
In addition, the normal control properties of .Index, .Left, .Top, .Tag,
.Parent and .hInternet are available for the ITC.
This table can be digested more easily if you think in terms of how the
properties/methods/events are used. Here's the way I've grouped them in
The bottom line of this tutorial section is that file transfers can be
made very easily using the ITC and just a handful of the properties,
methods and events supported by the control.
The .OpenURL and .Execute methods are the heart of using the ITC. Everything
you do requires the use of one of these two methods. The .GetChunk method
is used to capture data downloaded by the .Execute method.
The .URL, .Cancel, .StillExecuting, .ResponseCode, .ResponseInfo, .Cancel,
.GetChunk, and .GetHeader interface elements are used extensively during
The .AccessType, .Proxy, .Protocol, .RequestTimeout, .RemoteHost, .UserName,
.Password, and .RemotePort are very basic properties which you set once or
use the default - then you're done with them.
As a final note, in case you've been watching carefully you will notice
that I left out any discussion on the use of the .Execute method with
HTTP commands. This was strictly for lack of time/space in this tutorial.
The .Execute method can be used equally with either FTP or HTTP commands,
but the FTP options are generally more extensive so FTP is the normal choice
WinInet.dll - File Transfer Alternative
--- info on using wininet.dll goes here ----