Re: [Very slightly OT] Verbing with FTP
Re: [Very slightly OT] Verbing with FTP
- Subject: Re: [Very slightly OT] Verbing with FTP
- From: Greg Titus <email@hidden>
- Date: Wed, 14 Nov 2001 02:36:48 -0800
On Wednesday, November 14, 2001, at 12:05 AM, Sam Goldman wrote:
I am writing a cocoa app for connecting to FTP servers.
I can get to the point where I have just sent the USER, PASS, and PASV
verbs. I then get back a response from the server like this:
220 localhost FtP server (Verison 6.00LS) ready.
331 Password required for sgoldman
230 User sgoldman logged in.
227 Entering Passive Mode (127,0,0,1,193,175)
I know that I have to get this URL somehow 127.0.0.1:49583 where 49583 =
913*256+175.
Those of you that have done this know EXACTLY what the above means.
What I
first need to figure out is how to parse out "127.0.0.1:49583" from "227
Entering Passive Mode (127,0,0,1,193,175)" without quotes of course.
Okay, the fundamental thing you need to understand about the FTP
protocol is that the command-stream happens on one set of connected
sockets and any data passes along a separate set of connected sockets
(or more than one other set).
The neat thing about the protocol design is that it makes possible some
fun things like a client connecting to two different servers and
commanding server A to transfer files directly to server B. (In this
case there are two command connections, between client and A and client
and B. But there is only one data connection, between A and B.)
You've already opened the command stream (which is what you've passed
the first three commands along). The response to the PASV command you
are sending tells you where to connect to get a data stream going.
Next I want to get a directory listing. What do I do with this IP? I
would
be inclined to make another socket connection to the server and request
LIST
with LIST\015\012, but I don't know if that right. If I do need to make
another connection, do I need to send my USER and PASS verbs again?
Nope. You do not need to make another connection for sending the
command. Send the LIST command on the same socket that you already have
open. Read the response (probably "150 Opening ASCII mode data
connection ..blah blah..") on that same socket.
Then _also_ connect to the port that the server requests and read the
actual result of the LIST command. (The directory information.)
Finally there will be one more command response coming on the
command-stream: "226 Transfer Complete".
In short, what do I do after receiving the servers response to the PASV
verb
to get a directory listing.
From what I can understand. I don't have to use passive, but when I try
to
send the LIST verb right after logging in, the server refuses my
connection!
If you don't use passive mode then the data connection is formed in the
opposite connection - i.e. you (the client) tell the server to connect a
socket back to you in order to form the data connection. If the client
is behind a firewall this will generally not work, which is why almost
everyone uses passive mode these days.
The reason why the server is disconnecting you is because you are doing
a command that requires the server to give you data (LIST), but you
haven't told the server how to connect to you yet. To do that you would
need to use the PORT command, which is basically PASV in reverse... you
send your IP address and a port number where you've set up a listening
socket and the server connects back to you.
Hell, if you can understand that (I only partially do myself) I'd really
appreciate some help. I read numerous FTP Protocol references and
descriptions, but still can't figure it out.
Well, two more things you might want to look at (or that may confuse you
even more). There is an implementation of the FTP client-side in Omni's
OWF framework - look primarily at OWFTPSession.m. There is also an
implementation of the FTP server side in the small OmniFTPServer
framework, which you'll also find among our public frameworks on the
server (although it isn't mentioned on our web pages).
Hope this helps,
--Greg