有代码的android ftp4j.docx
《有代码的android ftp4j.docx》由会员分享,可在线阅读,更多相关《有代码的android ftp4j.docx(18页珍藏版)》请在冰豆网上搜索。
有代码的androidftp4j
FTP理论
FTP会话时包含了两个通道,一个叫控制通道,一个叫数据通道。
重点这个两个通道就是下面源码分析里面为什么通道会这么多……
控制通道:
控制通道是和FTP服务器进行沟通的通道,连接FTP,发送FTP指令都是通过控制通道来完成的。
数据通道:
数据通道是和FTP服务器进行文件传输或者列表的通道。
FTP协议中,控制连接均有客户端发起,而数据连接有两种工作方式:
PORT方式和PASV方式
PORT模式(主动方式)
FTP客户端首先和FTPServer的TCP21端口建立连接,通过这个通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。
PORT命令包含了客户端用什么端口(一个大于1024的端口)接收数据。
在传送数据的时候,服务器端通过自己的TCP20端口发送数据。
FTPserver必须和客户端建立一个新的连接用来传送数据。
PASV模式(被动方式)
在建立控制通道的时候和PORT模式类似,当客户端通过这个通道发送PASV命令的时候,FTPserver打开一个位于1024和5000之间的随机端口并且通知客户端在这个端口上传送数据的请求,然后FTPserver将通过这个端口进行数据的传送,这个时候FTPserver不再需要建立一个新的和客户端之间的连接传送数据。
好了理论就这么简单,再写下去自己就要睡着了,不过上面那个倒是重点,主要是为理解后面源码铺垫的,所以不能错过耶~~
FTP协议
ftp协议这里就不给那么多,给了估计大家看了也是白看(因为本人就是,多而枯燥,如果每样都去记这明显是笨蛋的行为,吃力而且效果不明显,这里就说到右脑开发,说白了就是文字图片记忆,虽然高中尝试过锻炼,不过后面自己觉得效果好像没什么显著,估计那个时候思维已经被这个社会的思维给框住了,多悲哀!
不过如果代码跟图片结合一起来记忆,效果还是明显。
举个例子和一个图片:
这张图片是我从某人的网站窃来的^-^
androidservice的思维导图,很明显这样代码跟图片一起结合使用,这个知识点你很快就记住了)
因此下面协议只列出本文章举例代码里面用到的,剩下的可以问谷老师。
命令
ACCT
系统特权帐号
LIST
如果是文件名列出文件信息,如果是目录则列出文件列表
MODE
传输模式(S=流模式,B=块模式,C=压缩模式)
NOOP
无动作,除了来自服务器上的承认
PASS
系统登录密码
PASV
被动模式,等待服务器告诉客户端去哪个端口建立连接
PORT
IP地址和两字节的端口ID
QUIT
从FTP服务器上退出登录
TYPE
数据类型(A=ASCII,E=EBCDIC,I=binary)
USER>
系统登录的用户名
响应代码
120
服务器准备就绪的时间(分钟数)
125
打开数据连接,开始传输
150
打开连接
200
成功
220
服务就绪
221
退出网络
227
进入被动模式(IP地址、ID端口)
230
登录因特网
331
要求密码
332
要求帐号
FTP服务器与客户端搭建
这里以Serv-U作为服务器,以LeapFTP3.0.1.46_yfy作为客户端来测试,搭建这个东西主要是为了测试服务器是否建立正确,确认后就可以开始动手做android客户端的。
服务器的搭建很简单,连我这种读过大学的人都知道,更何况那些没读过小学的(^-^这句话没逻辑错误吧)。
总的思路
1.创建核心类对象
2.建立socket连接
3.建立控制通道(命令通道)类
4.登陆
5.获取服务器目录文件信息
6.关闭连接
源码分析
这个源码分析倒没什么难点,跟之前分析androidsmack包源码差不多,基本都是以socket为核心,然后根据不同的协议定义不同的解释类,设计不同的项目框架。
(声明在看下面的文章时,最好先理解一下ftp4j的使用,这样才能更容易明白)
(谨记:
上图只显示本文章解释所要用到的类和方法,减缩了一些跟本文主题无关的代码或者一些判断,只留一条贯穿着从建立连接——获取服务器目录文件信息——关闭连接的线。
)
1.
建立FTPClient对象,连接服务器
ftp.connect("169.254.xxx.xxx",21);
publicString[]connect(Stringhost,intport)
throwsIllegalStateException,IOException,
FTPIllegalReplyException,FTPException{
synchronized(this.lock){
if(this.connected){
thrownewIllegalStateException("Clientalreadyconnectedto"
+host+"onport"+port);
}
Socketconnection=null;
try{
connection=this.connector.connectForCommunicationChannel(
host,port);
if(this.security==1){
connection=ssl(connection,host,port);
}
munication=newFTPCommunicationChannel(connection,
"UTF-8");
for(Iteratori=municationListeners.iterator();i
.hasNext();){
munication
.addCommunicationListener((FTPCommunicationListener)i
.next());
}
FTPReplywm=munication.readFTPReply();
if(!
wm.isSuccessCode()){
thrownewFTPException(wm);
}
this.connected=true;
//this.authenticated=false;
//this.parser=null;
this.host=host;
this.port=port;
this.username=null;
this.password=null;
this.utf8Supported=false;
this.restSupported=false;
this.mlsdSupported=false;
this.modezSupported=false;
//this.dataChannelEncrypted=false;
//Returnsthewelcomemessage.
returnwm.getMessages();
}catch(IOExceptione){
//D'oh!
throwe;
}finally{
//Ifconnectionhasfailed...
if(!
connected){
if(connection!
=null){
//Closetheconnection,'causeitshouldbeopen.
try{
connection.close();
}catch(Throwablet){
;
}
}
}
}
}
}
在连接服务器过程中,
connection=this.connector.connectForCommunicationChannel(host,port);
创建了控制通道的socket
munication=newFTPCommunicationChannel(connection,"UTF-8");
然后管理socket创建控制通道的管理类,监听信息入口的接收与发送,建立socket完成后通过FTPReplywm=munication.readFTPReply();获取服务器的信息,判断是否成功。
2.
publicFTPCommunicationChannel(Socketconnection,StringcharsetName)
throwsIOException{
this.connection=connection;
this.charsetName=charsetName;
InputStreaminStream=connection.getInputStream();
OutputStreamoutStream=connection.getOutputStream();
//Wrapthestreamsintoreaderandwriterobjects.
reader=newNVTASCIIReader(inStream,charsetName);
writer=newNVTASCIIWriter(outStream,charsetName);
}
privateStringread()throwsIOException{
//Readthelinefromtheserver.
Stringline=reader.readLine();
if(line==null){
thrownewIOException("FTPConnectionclosed");
}
//Callreceived()methodoneverycommunicationlistener
//registered.
for(Iteratoriter=communicationListeners.iterator();iter.hasNext();){
FTPCommunicationListenerl=(FTPCommunicationListener)iter.next();
l.received(line);
}
//Returnthelineread.
returnline;
}
publicvoidsendFTPCommand(Stringcommand)throwsIOException{
writer.writeLine(command);
for(Iteratoriter=communicationListeners.iterator();iter.hasNext();){
FTPCommunicationListenerl=(FTPCommunicationListener)iter.next();
l.sent(command);
}
}
监听socket信息接收与发送的管理类,该类