public class FtpLS {
    public final static boolean debug = true; //true for debug trace
    protected Socket ctlskt; //Control socket
    protected Socket datskt; //Data socket    protected InputStream datIn; //IO Stream for data socket
    protected OutputStream datOut; //IO Stream for data socket    protected BufferedReader ctlin; //Control port reader
    protected OutputStream ctlout; //Control port writer    public String lastResponse; //Last response from host
    public boolean passive = false; //passsive mode
public boolean connect(String host, String user, String pw)
    throws UnknownHostException, IOException {
    int status;
    ctlskt = new Socket(host, 21);
    ctlin = new BufferedReader(new InputStreamReader(ctlskt.getInputStream()));
    ctlout = ctlskt.getOutputStream();
    do {
        status = getResponse();
    } while (status != 220 && status != -1);
    if (status == -1)
        return false;
    status = sendCmd("USER " + user);
    if (status == 331)
        status = sendCmd("PASS " + pw);
    if (status == 332)
        return false;
    if (status != 230)
        return false;
    return true;
}
protected int dataSocket(String datCmd) throws IOException {
    int port;
    int status;    ServerSocket datsktsvr;
    if (passive) {
        StringBuffer IP = new StringBuffer();
        int i;
        status = sendCmd("PASV");
        if (status < 200 || status > 229)
            return -1;
        for (i = 4; i < lastResponse.length(); i++)
            if (Character.isDigit(lastResponse.charAt(i)))
                break;
        if (i == lastResponse.length())
            return -1; //not found
        StringTokenizer token = new StringTokenizer(lastResponse.substring(i), ",)");
        if (token.countTokens() != 6)
            return -1; //unknown IP/port
        for (i = 0; i < 4; i++) {
            IP.append(token.nextToken());
            if (i != 3)
                IP.append(".");
        }
        port = Integer.parseInt(token.nextToken()) * 256;
        port += Integer.parseInt(token.nextToken());
        datskt = new Socket(IP.toString(), port);
        status = sendCmd(datCmd);
    } else {
        datsktsvr = new ServerSocket(0);
        port = datsktsvr.getLocalPort();
        //set host/port
        StringBuffer cmd = new StringBuffer("PORT");
        cmd.append(ctlskt.getLocalAddress().getHostAddress());
        for (int i = 0; i < cmd.length(); i++) {
            if ('.' == cmd.charAt(i))
                cmd.setCharAt(i, ',');
        }
        cmd.append(",");
        cmd.append(Integer.toString(port / 256));
        cmd.append(",");
        cmd.append(Integer.toString(port & 0xFF));
        status = sendCmd(cmd.toString());
        if (status != 200)
            return -1;
        status = sendCmd(datCmd);
        //wait for remote connection
        datskt = datsktsvr.accept();
    }
    return 0;
}
public int getFile(String filename, BFile bfile) throws IOException {
    int status;
    status = dataSocket("RETR " + filename);
    if (status != 0)
        return status;
    datIn = datskt.getInputStream();    bfile.readFrom(datIn);//从IO流读取文件内容    datskt.close();
    return getResponse();
}
protected int getResponse() throws IOException {
    int n;
    String tmp;
    do {
        lastResponse = ctlin.readLine();
        if (debug)
            Log.debug("Debug Received:" + lastResponse);
    } while (lastResponse.charAt(3) == '-');
    tmp = lastResponse.substring(0, 3);
    try {
        n = Integer.parseInt(tmp);
    } catch (NumberFormatException e) {
        n = -1;
    }
    return n;
}
protected int sendCmd(String cmd) throws IOException {
    if (debug)
        Log.debug("Debug Send:" + cmd);
    String tmp = cmd + "\r\n";
    ctlout.write(tmp.getBytes());
    ctlout.flush();
    return getResponse();
}
}