Okay, it's late, but an idea that occurs to me would be to use a network traffic monitor like Wireshark to look at the connection attempt. (I mention Wireshark because it's the one I'm most familiar with, and can give a nicely parsed description of just what got sent in which direction:
220 dimacs.rutgers.edu FTP server (SunOS 5.8) ready.
USER anonymous
331 Guest login ok, send ident as password.
PASS mozilla@example.com
230 Guest login ok, access restrictions apply.
SYST
215 UNIX Type: L8 Version: SUNOS
PWD
257 "/" is current directory.
TYPE I
200 Type set to I.
PASV
227 Entering Passive Mode (128,6,75,16,200,215)
CWD /pub/
250 CWD command successful.
LIST
150 Binary data connection for /bin/ls (232.152.215.181,60475) (0 bytes).
226 Binary Transfer complete.
Between that and RFC 959 to find out what the response codes mean ("Service ready for new user", "User name okay, need password", "User logged in, proceed", "NAME system type.", etc., etc.) you'd at least be able to watch it fall over.
On a side note, while it won't help with connection problems, for the task your code illustrates the ftp:// stream wrapper would be more concise.