views:

4740

answers:

10

Sorry for the subject line sounding like an even nerdier Harry Potter title.

I'm trying to use AS3's Socket class to write a simple FTP program to export as an AIR app in Flex Builder 3. I'm using an FTP server on my local network to test the program. I can successfully connect to the server (the easy part) but I can't send any commands. I'm pretty sure that you have to use the ByteArray class to send these commands but there's some crucial piece of information that I'm missing apparently. Does anyone know how to do this? Thanks! Dave

A: 

Here's an example of what I'm trying to do that isn't working:

socket.writeUTFBytes("USER "+user+"\nPASS "+pass+"\nPASV\n"); socket.flush();

It doesn't do anything at all when I try to send this. Doesn't log in, doesn't tell me bad user/pass, nothing.

Dave Willis
A: 

We will need more info to resolve this.. What you're saying here appears correct to me. You're using the Socket class to send data though, not ByteArray.

Are you sure data is not being sent? How are you receiving the response? It may be that it's working fine but you're just not aware of it? As i said, tell us more about what you're doing..

Lee Brimelow has a screencast on gotoAndLearn of writing an POP3 client. It's essentially the same of what you're doing so take a look.

Antti
A: 

Yeah, I had tried to store the string in a ByteArray and then send the ByteArray but it didn't seem to make any difference. I am not sure that the data is being sent because I get no response at all. I get a response on connect so I know I'm connected but after that, nothing. I have these event listeners attached:

socket.addEventListener(Event.CONNECT, connectListener);
socket.addEventListener(Event.CLOSE, closeListener);
socket.addEventListener(ProgressEvent.SOCKET_DATA, dataListener);
socket.addEventListener(IOErrorEvent.IO_ERROR, errorListener);

Maybe I need a different event listener to get the responses? I don't know. Thanks!
Dave

Dave Willis
A: 

Are you 100% sure the syntax is correct? I know with HTTP you'll have to an include extra linebreak after the request for it to go through. Without it you'll get nothing back. Not sure how it is with FTP though.

Antti
A: 

The FTP standard requires CRLF at the end of commands. Try using "\r\n" in place of the "\n" in your example.

Darron
A: 

You must serve the CrossDomain Policy File from your FTP server in order to conect correctly.

A: 

From what I've gathered, you have to send each command one at a time and validate the response before moving on. You should be getting something back against ProgressEvent.SOCKET_DATA

Try just this and see what you get in response.

socket.writeUTFBytes("USER "+user+"\n"); socket.flush();

You would then read the response out like this.

var response:String = mySocket.readUTFBytes(mySocket.bytesAvailable);
seanalltogether
+2  A: 

The FTP protocol predates UTF encoding. Switch to ANSI/ASCII for better results. If you do opt for writeMultiByte instead of writeUTFBytes, be aware that it is buggy in linux. Here's one way around it.

There's another question here where the line ending turns out to be the culprit, so make sure that you get it right (as suggested above).

As said before, if this is running from the web, all socket connections will require a crossdomain policy, but this is NOT file based over HTTP. Recent changes to the security rules mean that any socket based connection must first get a crossdomain from a policy server hosted on port 843 of the target host.

Quoting from Adobe:

A SWF file may no longer make a socket connection to its own domain without a socket policy file. Prior to version 9,0,115,0, a SWF file was permitted to make socket connections to ports 1024 or greater in its own domain without a policy file.

HTTP policy files may no longer be used to authorize socket connections. Prior to version 9,0,115,0, an HTTP policy file, served from the master location of /crossdomain.xml on port 80, could be used to authorize a socket connection to any port 1024 or greater on the same host.

Essentially, what this means is that you must be in control of the target FTP host, and install supplementary software on it to get this working.

spender
He could go through his own host to avoid that.
Wouter Lievens
I agree, but have never been in a position to shoulder the bandwidth that this would incur
spender
+1  A: 

Read this link too and maybe it can be useful this one too.

The first one is about policy files and the second is an example of a TELNET (so, no FTP here) client.

A: 

I've been able to get an FTP client working in a browser, but it's buggy. I had to get a listener running on port 843 to server the policy file so that Flash would be allowed to connect and transfer data. Then, I had to figure out how FTP actually works:

You have to open 2 sockets: a command socket and a data socket. The command socket is where you send your USER, PASS, CWD, and STOR commands. The data socket is where you write your ByteArray data to. Sending the PASV command will tell you what port your data socket must connect to.

Where it is buggy is on Mac, in both Safari and FF, when I call the "socket.close()" command, the server socket actually closes. On Windoze, it does not. This is a huge problem because the Event.CLOSE event is not fired until the SERVER closes the connection. This is in the livedocs.

This is where I'm at. I have no idea why it would work flawlessly on Mac and then be completely busted in 3 different browsers on Windows. The only thing I can come up with is that it's either something in my Windows configuration that's preventing proper communication with the server, or it's the Window Flash player that's causing the problem.

Any thoughts?

DF