平台
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客户端简单实现