Android FTP Client 实现

平台

Android 7.1 + AndroidStudio 4.1.2

需求

实现FTP客户端功能

实现

服务端: 客户使用pure-ftpd搭建了一个FTP服务器 (IP: 1.2.3.4)


Ubuntu FTP服务器搭建
参考:ubuntu下安装pure-ftpd记录

# 安装
sudo apt-get install pure-ftpd

装完后, 使用ftp连接, 并输入用户名密码, 即可访问FTP服务

# 连接
ftp localhost
Connected to localhost.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 09:19. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (localhost:anson): 
331 User anson OK. Password required
Password:
230 OK. Current directory is /home/anson
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful
150 Connecting to port 46661
drwxr-xr-x    2 anson      anson            4096 Feb 20 09:12 Desktop
drwxr-xr-x    2 anson      anson            4096 Dec 25 21:57 Documents
drwxr-xr-x    5 anson      anson            4096 Mar  3 16:05 Downloads
drwxr-xr-x    2 anson      anson            4096 Dec 25 21:57 Music
drwxr-xr-x    5 anson      anson            4096 Mar  3 14:12 Pictures
drwxr-xr-x    2 anson      anson            4096 Dec 25 21:57 Public
drwxrwxr-x    4 anson      anson            4096 Feb 19 17:16 StudioProjects
drwxr-xr-x    2 anson      anson            4096 Dec 25 21:57 Templates
drwxr-xr-x    2 anson      anson            4096 Feb 23 17:06 Videos
#添加ftp用户组
sudo groupadd ftpgroup

#添加虚拟用户
#sudo pure-pw useradd bbm -u anson -g ftpgroup -d /home/anson/Downloads/ftpbbm
#> ERROR: You must give (non-root) uid and gid

#添加FTP用户
sudo useradd ftp -g ftpgroup -d /home/anson/Downloads/ftp -s /sbin/nologin

#添加虚拟用户
sudo pure-pw useradd bbm -u ftp -g ftpgroup -d /home/anson/Downloads/ftp/bbm

sudo pure-pw mkdb

#解决登陆问题
#530 Login authentication failed
sudo ln -s /etc/pure-ftpd/conf/PureDB /etc/pure-ftpd/auth/PureDB

#生启生效
sudo /etc/init.d/pure-ftpd restart

上传失败

# FTP目录权限问题
chown ftp:ftpgroup /home/anson/Downloads/ftp/bbm

完成


客户端:

  • LINUX: ftp命令:
ftp 1.2.3.4
Connected to 1.2.3.4
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 16:39. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (1.2.3.4:user): bbm
331 User bbm OK. Password required
Password:
230 OK. Current directory is /
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful
150 Connecting to port 54375
lrwxrwxrwx    1 0          0                  26 Mar  2 14:59 PureDB -> /etc/pure-ftpd/conf/PureDB
drwxr-xr-x    2 0          0                4096 Mar  2 14:52 message
drwxr-xr-x    2 0          0                4096 Mar  2 14:52 music
drwxr-xr-x    2 0          0                4096 Mar  2 14:52 photo
drwxr-xr-x    2 0          0                4096 Mar  2 14:56 video
226-Options: -l 
226 5 matches total
ftp> quit
221-Goodbye. You uploaded 0 and downloaded 0 kbytes.
221 Logout.
  • Window + FlashFTP, 可以登陆, 但没有文件列表, 也报错
FlashFXP 5.4.0 (build 3970)
Support Forums https://www.flashfxp.com/forum/

[15:24:49] Winsock 2.2 -- OpenSSL 1.1.0e  16 Feb 2017
[15:25:23] [R] 正在连接到 1.2.3.4 -> IP=1.2.3.4 PORT=21
[15:25:24] [R] 已连接到 1.2.3.4
[15:25:25] [R] 220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
[15:25:25] [R] 220-You are user number 2 of 50 allowed.
[15:25:25] [R] 220-Local time is now 15:25. Server port: 21.
[15:25:25] [R] 220-This is a private system - No anonymous login
[15:25:25] [R] 220-IPv6 connections are also welcome on this server.
[15:25:25] [R] 220 You will be disconnected after 15 minutes of inactivity.
[15:25:25] [R] USER bbm
[15:25:25] [R] 331 User bbm OK. Password required
[15:25:25] [R] PASS (hidden)
[15:25:25] [R] 230 OK. Current directory is /
[15:25:25] [R] SYST
[15:25:25] [R] 215 UNIX Type: L8
[15:25:25] [R] FEAT
[15:25:25] [R] 211-Extensions supported:
[15:25:25] [R]  EPRT
[15:25:25] [R]  IDLE
[15:25:25] [R]  MDTM
[15:25:25] [R]  SIZE
[15:25:25] [R]  MFMT
[15:25:25] [R]  REST STREAM
[15:25:25] [R]  MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
[15:25:25] [R]  MLSD
[15:25:25] [R]  AUTH TLS
[15:25:25] [R]  PBSZ
[15:25:25] [R]  PROT
[15:25:25] [R]  UTF8
[15:25:25] [R]  TVFS
[15:25:25] [R]  ESTA
[15:25:25] [R]  PASV
[15:25:25] [R]  EPSV
[15:25:25] [R]  SPSV
[15:25:25] [R]  ESTP
[15:25:25] [R] 211 End.
[15:25:25] [R] OPTS UTF8 ON
[15:25:25] [R] 200 OK, UTF-8 enabled
[15:25:25] [R] PWD
[15:25:25] [R] 257 "/" is your current location
[15:25:25] [R] PASV
[15:25:25] [R] 227 Entering Passive Mode (172,27,207,6,179,96)
[15:25:25] [R] 正在打开数据连接 IP: 1.2.3.4 端口: 45920
[15:25:46] [R] 数据套接字错㿯 

查询到的一些资料(前面搭建的FTP服务器并未出现此问题, 仅记录 未尝试):
开启阿里云linux下的pure-ftpd被动模式,解决flashfxp可连接但无法下载的问题
linux系统宝塔控制面板下建立pure-ftpd用FlashFXP链接报错421以及530的解决办法


  • Android[本文重心]
    实现的方法其实有很多, 以前用过ftp4j, 今天尝试使用Apache Commons Net
    Apache Commons Net
    Apache Commons Net 3.8.0 API
    下载 commons-net-3.8.0-bin.tar.gz
    解压:
~/Downloads$ ll commons-net-3.8.0
total 876
drwxrwxr-x 4 anson anson   4096 3月   3 16:05 ./
drwxr-xr-x 5 anson anson   4096 3月   3 16:05 ../
drwxrwxr-x 4 anson anson   4096 3月   3 16:05 apidocs/
-rw-r--r-- 1 anson anson 307305 1月  22  2020 commons-net-3.8.0.jar
-rw-r--r-- 1 anson anson 437325 1月  22  2020 commons-net-3.8.0-sources.jar
-rw-r--r-- 1 anson anson  92684 1月  22  2020 commons-net-examples-3.8.0.jar
-rw-r--r-- 1 anson anson  11358 1月  22  2020 LICENSE.txt
-rw-r--r-- 1 anson anson    173 1月  22  2020 NOTICE.txt
drwxrwxr-x 3 anson anson   4096 3月   3 16:05 org/
-rw-r--r-- 1 anson anson   5749 1月  22  2020 README.md
-rw-r--r-- 1 anson anson   8785 1月  22  2020 RELEASE-NOTES.txt

再把commons-net-3.8.0.jar加入的Studio项目信赖.


import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
public class FtpClient extends Activity {
    final String TAG = "FtpClient";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ftp_client);

        new Thread(){
            @Override
            public void run() {
                try {
                    //创建和连接
                    FTPClient ftpClient = new FTPClient();
                    ftpClient.connect("1.2.3.4");
                    ftpClient.login("user", "12345678");
                    ftpClient.changeWorkingDirectory("/");
                    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                    FTPFile[] fs = ftpClient.listDirectories();

                    //输出文件数量
                    Logger.d(TAG, "fs.size=" + (fs == null ? -1 : fs.length));
                    for(FTPFile f : fs){
                        //打印文件名
                        Logger.d(TAG, f.getName());
                    }
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}

结果

FtpClient: ALog > fs.size=4
FtpClient: ALog > message
FtpClient: ALog > music
FtpClient: ALog > photo
FtpClient: ALog > video

参考

Android FTP Library [closed]
android ftp客户端简单实现

你可能感兴趣的:(android,Linux,FTP,Apache)