经过了几天的研究,终于Apache FTPServer在Android的配置和使用上有了一些心得,现在分享出来,提供给大家参考,说到这儿又不得不吐槽一下这要命的转载了,找Apache FTPServer方面的资料网上千篇一律的都是同一个人的博客,而且这个博客的很多东西还是说的比较模糊的,初次使用的人根本看不懂啊,搞毛啊,逼这我不得不再次写一篇东西出来。

还是按照步骤来叙述吧。

1.从Apache官网上下载Apache FTPServer的Released版本,地址为 http://mina.apache.org/ftpserver-project/downloads.html

2.下载完之后可以看到是一个文件夹apache-ftpserver-1.0.6。然后新建一个Android的项目,本人新建的项目是Android 2.2的项目。

3.拷贝apache-ftpserver-1.0.6/common/lib 目录下的 ftpserver-core-1.0.6.jar、log4j-1.2.14.jar、mina-core-2.0.4.jar、slf4j-api-1.5.2.jar、slf4j-log4j12-1.5.2.jar 这些文件到你新建的Android项目目录下的libs目录下,其他不用拷贝。

4.在你的Android项目中res文件夹下新建raw目录,然后拷贝/Users/lixing/Downloads/apache-ftpserver-1.0.6/res/conf/users.properties 文件到raw目录下面去。

5.打开你的Android项目中的 users.properties文件,把内容修改为如下内容,下面解释下这个内容的含义:

# Password is "admin"

ftpserver.user.admin.userpassword=21232F297A57A5A743894A0E4A801FC3

ftpserver.user.admin.homedirectory=/sdcard/

ftpserver.user.admin.enableflag=true

ftpserver.user.admin.writepermission=true

ftpserver.user.admin.maxloginnumber=20

ftpserver.user.admin.maxloginperip=5

ftpserver.user.admin.idletime=300

ftpserver.user.admin.uploadrate=4800000

ftpserver.user.admin.downloadrate=4800000

ftpserver.user.zhangsan.userpassword=21232F297A57A5A743894A0E4A801FC3

ftpserver.user.zhangsan.homedirectory=/sdcard/

ftpserver.user.zhangsan.enableflag=true

ftpserver.user.zhangsan.writepermission=true

ftpserver.user.zhangsan.maxloginnumber=20

ftpserver.user.zhangsan.maxloginperip=5

ftpserver.user.zhangsan.idletime=300

ftpserver.user.zhangsan.uploadrate=4800000

ftpserver.user.zhangsan.downloadrate=4800000

解释一下,上面这些内容实际上是Apache FTPServer的用户配置文件,主要是用来配置FTP的登录用户信息,我们可以看到这个配置文件里面描述了两个用户,一个用户名是admin,另外一个用户是zhangsan,没错,你没有看错,就是这样的,如果你要添加新的用户,可以使用这个格式 如 ftpserver.user.用户名.XXXX

对于单个用户,这里一行一行的解释

第一行:设置用户的登录密码 ,这个密码是MD5加密的,所以看起来有点儿奇怪,目前示例中的这个密码是admin的MD5加密值

第二行:设置FTP用户的根目录,因为我们是手机,所以我现在将这个目录设置为我的手机的Sd卡的根目录

第三行:设置这个登录账户是否被启用

第四行:设置这个账户是否具有可写的权限。

第五行:这个用户的同一时间最大的的登录用户数量,这里设置大一点,没什么问题,设置小了会出现总是登录不成功的情况

第六行:设置最大的登录IP数量,这里也设置大一点,原因同上

第七行:超时时间

第八行:上传速度,这里设置的比较大,最少字面上的意思是这样的,但是我不得不说你需要设置的大一些,否则你会发现你根本无法上传大文件,可能是一个bug吧,要注意

第九行:下载速度,这里设置的比较大,原因同上

6.新建一个java类,然后把下面代码粘贴进去,具体需要新建的layout我就不说了,自己对照着新建就行了

package xing.li;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory; import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity { private FtpServer mFtpServer;
private int port =2222;// 端口号
private String ftpConfigDir = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/ftpConfig/"; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); TextView tv = (TextView) findViewById(R.id.tvText);
String info = "请通过浏览器或者我的电脑访问以下地址\n" + "ftp://" + getLocalIpAddress()
+ ":" + port + "\n";
tv.setText(info); Button btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
File f = new File(ftpConfigDir);
if (!f.exists())
f.mkdir();
copyResourceFile(R.raw.users, ftpConfigDir + "users.properties");
Config1();
}
});
Button btnStop = (Button) findViewById(R.id.btnStop);
btnStop.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
mFtpServer.stop();
}
}); File f = new File(ftpConfigDir);
if (!f.exists())
f.mkdir();
copyResourceFile(R.raw.users, ftpConfigDir + "users.properties");
copyResourceFile(R.raw.users, ftpConfigDir + "ftpserver.jks"); Config1();
} public String getLocalIpAddress() {
String strIP = null;
try {
for (Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf
.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
strIP = inetAddress.getHostAddress().toString();
}
}
}
} catch (SocketException ex) {
Log.e("msg", ex.toString());
}
return strIP;
} private void copyResourceFile(int rid, String targetFile) {
InputStream fin = ((Context) this).getResources().openRawResource(rid);
FileOutputStream fos = null;
int length;
try {
fos = new FileOutputStream(targetFile);
byte[] buffer = new byte[1024];
while ((length = fin.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} void Config1() {
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory(); String[] str = { "mkdir", ftpConfigDir };
try {
Process ps = Runtime.getRuntime().exec(str);
try {
ps.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String filename = ftpConfigDir + "users.properties";
File files = new File(filename);
userManagerFactory.setFile(files);
serverFactory.setUserManager(userManagerFactory.createUserManager()); factory.setPort(port);
try {
serverFactory.addListener("default",factory.createListener());
FtpServer server = serverFactory.createServer();
this.mFtpServer = server; server.start();
} catch (FtpException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy(); if (null != mFtpServer) {
mFtpServer.stop();
mFtpServer = null;
}
} }

 7,一切搞掂了就可以运行一下了,运行完毕了之后,就在同一个网络中的ftp客户端中试着链接一下,注意要修改一下ftp的客户端里面的 被动模式 为 主动模式这样才可以连接上啊,这是血的教训,老子调试了一整天才搞定,头都搞大了。你要是问我怎样修改服务端让他客户端链接的时候直接成为被动模式,不好意思,我也不知道,这个不知道三个字的得来也废了老子一整天时间。

android学习:Android上面部署Apache FTPServer的更多相关文章

  1. android学习——android架构

    android架构:在了解全局的情况下进行细致化的分析才能更有效的学习android的运行原理,才能更深刻的理解android开发: 1.架构图直观 2.架构详解 2.1.Linux Kernel 2 ...

  2. android学习——Android Layout标签之-viewStub,requestFocus,merge,include

    定义Android Layout(XML)时,有四个比较特别的标签是非常重要的,其中有三个是与资源复用有关,分别是<viewStub/>, <requestFocus />, ...

  3. android学习——android项目的的目录结构

       然后我们看一下Helloword的程序目录: 我们可以看到 大致有的文件: 1. MainHelloWorld.java文件 2. R.java文件 3. android.jar文件 4. RE ...

  4. android学习——Android Studio下创建menu布局文件

    一.问题: android studio项目中没有看到menu文件夹: 在android studio项目中想要添加menu布局文件,一开始我的做法是:直接在res文件夹右键选择xml文件来添加,如下 ...

  5. Android学习----Android架构

    android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和linux核心层.蓝色的代表java程序,黄色的代码为运行JAVA程序而实现的虚拟机,绿色部分为C/C++语言编写 ...

  6. openfire Android学习---android客户端聊天开发之登录 和 注销登录

    一切就绪,新建一个android测试工程: 上网权限配置,界面绘制啥的,这里就不说了. 首先 导入一个smark包.这个是用来维护长连接的,也可以是asmark.我用的是asmark 先普及一些基本知 ...

  7. android学习——android 常见的错误 和 解决方法

    1. Application does not specify an API level requirement! 解决方法:AndroidManifest.xml中 加入: <uses-sdk ...

  8. Android学习----Android Studio 技巧汇总

    关于快捷键 The File Structure Popup ctrl+f12此快捷键可以调出当前文件的大纲,并通过模糊匹配快速跳转至指定的方法.勾选上“show anonymous classes” ...

  9. Android学习–Android app 语言切换功能

    功能: app用户根据自己的语言喜好,设置app语言.语言设置只针对本app,并在下次启动应用时保留前一次启动设置. 更新语言: public static void changeAppLanguag ...

随机推荐

  1. php里单引和双引的用法区别和连接符(.)

    " "双引号里面的字段会经过编译器解释,然后再当作HTML代码输出. ' '单引号里面的不进行解释,直接输出. 例如: $abc='my name is tome'; echo $ ...

  2. 新手嘛,先学习下 Vue2.0 新手入门 — 从环境搭建到发布

    Vue2.0 新手入门 — 从环境搭建到发布 转自:http://www.runoob.com/w3cnote/vue2-start-coding.html 具体文章详细就不搬了,步骤可过去看,我这就 ...

  3. 重温C语言(1)----计算算术表达式的值

    <C程序设计语言>练习题 5-10 编写程序 expr,计算从命令行输入的逆波兰表达式的值,其中每个运算符或操作数用一个单独的参数表示.例如,命令 expr 2 3 4 + * 计算表达式 ...

  4. Oracle PL/SQL Dev工具(破解版)被植入勒索病毒的安全预警及自查通告

    [问题描述] 近日,有项目组遇到了勒索软件攻击:勒索代码隐藏在Oracle PL/SQL Dev软件中(网上下载的破解版),里面的一个文件afterconnet.sql被黑客注入了病毒代码.这个代码会 ...

  5. Sql Server增加Sequence序列语句

    1.创建序列 下面的示例创建名为 DecSeq 使用一个序列 十进制 具有介于 0 到 255 之间的数据类型.序列以 125 开始,每次生成数字时递增 25. 因为该序列配置为可循环,所以,当值超过 ...

  6. C# winfrom Datagridview控件下拉菜单

    拖拽一个datagridview放在界面,编辑列把下来菜单那列ColumnType设置成DataGridViewComboBoxColumn 然后在数据一栏的Items可以写下来菜单的内容也可以后台代 ...

  7. 深入浅出SharePoint2010——请假系统无代码篇之工作流设计

    使用SharePoint Designer 2010进行设计. 主要使用的Actions如下图所示. 关于权限,考虑到严谨的权限设计,所以所有参与人员均为Read权限. 关于请假天数的计算,请假天数的 ...

  8. Bypass xss过滤的测试方法

    0x00 背景 本文来自于<Modern Web Application Firewalls Fingerprinting and Bypassing XSS Filters>其中的byp ...

  9. Django F对象的使用

    概念 class FF()是代表模型字段的值,也就是说对于一些特殊的字段的操作,我们不需要用Python把数据先取到内存中,然后操作,在存储到db中了. 场景 例1:我们有个统计点击量的字段,每次更新 ...

  10. webkit架构

    简要的说,WebKit由三个模块组成:JavaScriptCore.WebCore 和 WebKit.WebKit作为了整个项目的名称. JavaScriptCore:是JavaScript解释器: ...