FTP Command Demo: Using the FTP Client
An FTP client allows lower-level access to the FTP protocol than the FTP agent provides. The
RWFtpClient class is for developers who require complete control over the protocol.
Example 3 demonstrates how to use some of the basic FTP commands in class
RWFtpClient, such as
USER,
PASS,
LIST,
CWD,
PWD, and
RETR. First, a connection must be established between a client and an FTP server of interest. Then the
USER/
PASS protocol command sequence must be performed before most other commands can be issued. If any command is conducted out of order, an exception is thrown.
NOTE: Servers and files shown in the code might not exist and are included as examples only.
Example 3 – Using basic FTP commands
// global variable client
RWFtpClient client; // 1
bool
ftpConnect(const RWCString& machine)
{
...
reply = client.connect(machine); // 2
...
}
bool
ftpUser(const RWCString& user)
{
...
RWFtpReply reply = client.user(user); // 3
...
}
bool
ftpPass(const RWCString& pass)
{
...
RWFtpReply reply = client.pass(pass); // 4
...
}
bool
ftpList(const RWCString& dir)
{
try {
RWFtpDataReply dataReply = client.list(dir); // 5
cout << dataReply << endl;
if (!dataReply.is1XX()) return FALSE; // 6
RWCString line;
RWPortalIStream strm(dataReply.portal()); // 7
while (l) {
line.readline(strm); // 8
if (line.isNull()) break; // 9
cout << line <<endl;
}
RWFtpReply reply = client.dataClose(); //10
cout << reply << endl;
if (!reply.is2XX()) return false; //11
}
catch (const RWxmsg& m) { //12
cout << m.why() << endl;
return false;
}
return true;
}
NOTE: The default data connection direction is used. For other ways to specify the data connection direction, see
Using Active and Passive Clients. Keep in mind that the direction of data connection is not related to the direction of data transfer. It is purely a connection construction issue.
NOTE: The dataClose() method needs to be invoked for each data transfer session. This is because the FTP protocol creates a data connection for each data transfer session that must be removed afterwards.
In this example, the return values of all FTP command requests that return
RWTIOUResults with a redeemable
RWFtpReply (or its derived class) are assigned to an object of
RWFtpReply. This causes the current thread to block until the actual result of the reply becomes available. In other words, the redeemable is redeemed immediately by blocking the thread. This is one way of redeeming an
RWTIOUResult object. See
Multithreading and IOUs and
File Retrieval: Using the FTP Agent (Part II) for other ways of redeeming an
RWTIOUResult.