using ftplib

Dave Hughes dave at
Mon May 1 22:49:01 CEST 2006

John Salerno wrote:

> I'm experimenting with this now and I'm a little confused about
> transferring commands. This might be more of an FTP question than
> strictly Python, but it's still related to how to use the ftplib
> methods.
> Anyway, if what I want to do is send a command to change the file
> permission settings of a file (or files), I assume I would use
> transfercmd() and the command would be something like SITE CHMOD 755
>, for example.
> What I'm confused about is why the documentation says to send a PORT
> or PASV command as well. Is this just something that must be done
> before each command?
> Also, in order to figure out what the FTP commands are to begin with,
> I did a little testing in FileZilla and I noted what was being
> displayed at the top (things like PORT xxx, STOR xxx, SITE CHMOD,
> etc. depending on what I was doing). So I assume these are the 'cmd'
> parameter. So here are a couple of questions:
> 1. Are PORT/PASV necessary to start a transfer?

Indeed. FTP is a tricky (and _very_ old) protocol that does things in a
very different manner to the later (simpler) protocols like HTTP. Not
sure how familiar you are with FTP, so my apologies if I wind up
repeating stuff you know already:

FTP sessions typically have *two* connections: the "control"
connection, and the "data" connection. The control connection is from
the client to the server (typically port 21 on the server side), and is
used to send commands to the server and obtain responses.

The PORT command tells the server to open a data connection to the
client (yes, that's not a typo: from the server to the client) and the
parameters tell the server the address and port to connect to. This is
the "active" (or default) mode for FTP (although due to the heavy use
of NAT these days, "passive" mode is probably as, or more common in

The PASV command is the reverse of the PORT command: it requests the
server listen on a new port for a data connection from the client to
the server.

Data is never transferred over the control connection, it always goes
over the separate data connection, hence why PORT or PASV are required
before initiating a transfer.

See RFC 959 for the full spec (gawd, it's been a long time since I read
that ... amazed I still remember the number):

> 2. Is the cmd parameter some kind of list, or is it just a string and
> you have to call a separate transfercmd() for each command?

Sorry, I haven't used ftplib yet, but a brief glance at the code
suggests to me that it's just a string and you probably do need to call
a separate transfercmd for each command.

> 3. My burning question: also during every transfer I made in
> FileZilla, I see that it sometimes sends a TYPE A or TYPE I command
> as well. What are these, and are they also necessary when I'm using
> transfercmd()?

TYPE I indicates that an "Image" transfer is to take place (though this
is more commonly referred to nowadays as a "binary" transfer). In an
binary transfer the data is transferred verbatim with no

TYPE A indicates that an ASCII transfer is to take place. An ASCII
transfer is intended for use with text files and indicates that the
data should be transformed from the native text format on the client
platform to the native text format on the server platform. For example,
transferring a file from a DOS/Windows client to a UNIX/Linux platform
in ASCII mode would convert CRLF line endings (ASCII char 13 + ASCII
char 10) to LF line endings (ASCII char 10).

There are other transfer modes as well, though I forget exactly what
they are (there's probably one for EBCDIC <shudder> :-).

Take a look at the storbinary, storlines, retrbinary and retrlines
methods of the FTP object: looks like they perform the appropriate TYPE
command for you, then pass the specified command to transfercmd.



More information about the Python-list mailing list