android学习:Android上面部署Apache FTPServer
经过了几天的研究,终于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的更多相关文章
- android学习——android架构
android架构:在了解全局的情况下进行细致化的分析才能更有效的学习android的运行原理,才能更深刻的理解android开发: 1.架构图直观 2.架构详解 2.1.Linux Kernel 2 ...
- android学习——Android Layout标签之-viewStub,requestFocus,merge,include
定义Android Layout(XML)时,有四个比较特别的标签是非常重要的,其中有三个是与资源复用有关,分别是<viewStub/>, <requestFocus />, ...
- android学习——android项目的的目录结构
然后我们看一下Helloword的程序目录: 我们可以看到 大致有的文件: 1. MainHelloWorld.java文件 2. R.java文件 3. android.jar文件 4. RE ...
- android学习——Android Studio下创建menu布局文件
一.问题: android studio项目中没有看到menu文件夹: 在android studio项目中想要添加menu布局文件,一开始我的做法是:直接在res文件夹右键选择xml文件来添加,如下 ...
- Android学习----Android架构
android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和linux核心层.蓝色的代表java程序,黄色的代码为运行JAVA程序而实现的虚拟机,绿色部分为C/C++语言编写 ...
- openfire Android学习---android客户端聊天开发之登录 和 注销登录
一切就绪,新建一个android测试工程: 上网权限配置,界面绘制啥的,这里就不说了. 首先 导入一个smark包.这个是用来维护长连接的,也可以是asmark.我用的是asmark 先普及一些基本知 ...
- android学习——android 常见的错误 和 解决方法
1. Application does not specify an API level requirement! 解决方法:AndroidManifest.xml中 加入: <uses-sdk ...
- Android学习----Android Studio 技巧汇总
关于快捷键 The File Structure Popup ctrl+f12此快捷键可以调出当前文件的大纲,并通过模糊匹配快速跳转至指定的方法.勾选上“show anonymous classes” ...
- Android学习–Android app 语言切换功能
功能: app用户根据自己的语言喜好,设置app语言.语言设置只针对本app,并在下次启动应用时保留前一次启动设置. 更新语言: public static void changeAppLanguag ...
随机推荐
- 解决chrome提示您的连接不是私密连接的方法
升级到最新的chrome , 开始报开发环境的证书错误问题 升级前,至少还有个可以添加例外,这个挺爽, 都不给设置. 网上找了找,有个解决方式 将选项卡切换至“快捷方式”栏,在目标的最 ...
- 工具Sequel Pro简介
从图中可以看到,sequel工作界面主要分成三部分,左边侧边显示的是当前所连接的数据库中存在的数据表,右侧上半部分则是用于写sql的地方,在Mac环境下按command+R键会执行你所写的sql,右侧 ...
- EF6 按条件更新多行记录的值
using (var db = new MyDbContext()) { string fromUser = ""; //sender string toUser = " ...
- c# 调用 c dll 例子
// case 1 传递 int* ///////////////////////////////////////////// extern “C” __declspec(dllexport) int ...
- 网络爬虫入门(二)模拟提交以及HttpClient修正
模拟提交就是说我们不自己登陆到客户端,仅仅靠发送请求就模拟了客户端的操作,在现实使用的时候经常用来接收一些需要登录才能获取到的数据,来模拟表单的提交,所以很多时候也被称作虚拟登录,这次的例子是我自己为 ...
- BigInteger方法总结
BigInteger 可以用来解决数据的溢出问题. 下面我总结几种关于BigInteger的常用用法: 1.probablePrime和nextprobablePrime.(判断质数,并返回) Big ...
- Django 简单教程(入门级)
一.Django简介 1. web框架介绍 具体介绍Django之前,必须先介绍WEB框架等概念. web框架: 别人已经设定好的一个web网站模板,你学习它的规则,然后“填空”或“修改”成你自己需要 ...
- Django 代码初体验
其实Django中的代码逻辑就是和我们以前所学的一些项目差不多 就是 解耦.解耦.解耦 创建过后的Django文件 其中的day68是你的 项目的名字的相同的一个自动生成的文件里面都是放置配置文件类似 ...
- haproxy开启日志功能
haproxy在默认情况不会记录日志,除了在haproxy.conf中的global段指定日志的输出外,还需要配置系统日志的配置文件.下面以centos6.4为例,haproxy使用系统自带的rpm报 ...
- oracle中RAW数据类型
近日在研究v$latch视图时,发现一个从未见过的数据类型.v$latch 中ADDR属性的数据类型为RAW(4|8) 同时也发现v$process中的ADDR属性的数据类型也为RAW(4|8).于 ...