老板让做的用Android做热点,同时作为FTP服务器。网上的都在吐槽其他人的不好使,结果页没有一个能好使的,最后还是靠Stack Overflow完成了初试验!
在我的电脑或者浏览器里输入FTP地址、账号密码就能实现文件互传了!HIAHIAHIA!
Apache官网可以下载最新的Apache FtpServer 1.0.6 Release,先将解压后\apache-ftpserver-1.0.6\common\lib路径下的
这几个jar包复制到project/libs内,然后Eclipse内打开project,在project上右键-->properties-->Java Build Path-->Libraries-->Add External JARs,选择刚才导入的几个jar包。
由于要使用一个用户配置文件的copy,所以在project/res/下新建raw文件夹,新建文件users.properties,复制如下内容:
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# reanonymousding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Password is "admin"
ftpserver.user.admin.userpassword=admin
ftpserver.user.admin.homedirectory=/
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.anonymous.userpassword=
ftpserver.user.anonymous.homedirectory=/
ftpserver.user.anonymous.enableflag=true
ftpserver.user.anonymous.writepermission=true
ftpserver.user.anonymous.maxloginnumber=20
ftpserver.user.anonymous.maxloginperip=5
ftpserver.user.anonymous.idletime=300
ftpserver.user.anonymous.uploadrate=4800000
ftpserver.user.anonymous.downloadrate=4800000
然后在AndroidManifest.xml文件内添加权限:
下面上代码:
FTPLetImpl.java
package com.example.ftptest02;
import java.io.IOException;
import org.apache.ftpserver.ftplet.DefaultFtplet;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.ftplet.FtpSession;
import org.apache.ftpserver.ftplet.FtpletResult;
public class FTPLetImpl extends DefaultFtplet {
@Override
public FtpletResult onLogin(FtpSession session, FtpRequest request) throws FtpException, IOException {
System.out.println(session.getUser().getName() + " Logged in");
return super.onLogin(session, request);
}
@Override
public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException {
System.out.println(session.getUser().getName() + " Disconnected");
return super.onDisconnect(session);
}
@Override
public FtpletResult onDownloadStart(FtpSession session, FtpRequest request) throws FtpException, IOException {
System.out.println(session.getUser().getName() + " Started Downloading File " + request.getArgument());
return super.onDownloadStart(session, request);
}
@Override
public FtpletResult onDownloadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException {
System.out.println("Finished Downloading " + request.getArgument());
return super.onDownloadEnd(session, request);
}
}
SFTPServer.java
package com.example.ftptest02;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.ftpserver.ConnectionConfigFactory;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.ConcurrentLoginPermission;
import org.apache.ftpserver.usermanager.impl.TransferRatePermission;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import android.os.Environment;
public class SFTPServer {
// ===========================================================
// Constants
// ===========================================================
private final int FTP_PORT = 2221;
private final String DEFAULT_LISTENER = "default";
// private final Logger LOG = LoggerFactory.getLogger(SFTPServer.class);
private static final List ADMIN_AUTHORITIES;
private static final int BYTES_PER_KB = 1024;
private static String ftpConfigDir= Environment.getExternalStorageDirectory().getAbsolutePath()+"/ftpConfig/";
private static final String DEFAULT_USER_DIR = ftpConfigDir;
public final static int MAX_CONCURRENT_LOGINS = 1;
public final static int MAX_CONCURRENT_LOGINS_PER_IP = 1;
// ===========================================================
// Fields
// ===========================================================
private static FtpServer mFTPServer;
private static UserManager mUserManager;
private static FtpServerFactory mFTPServerFactory;
private ListenerFactory mListenerFactor;
// ===========================================================
// Constructors
// ===========================================================
static {
// Admin Authorities
ADMIN_AUTHORITIES = new ArrayList();
ADMIN_AUTHORITIES.add(new WritePermission());
ADMIN_AUTHORITIES.add(new ConcurrentLoginPermission(MAX_CONCURRENT_LOGINS, MAX_CONCURRENT_LOGINS_PER_IP));
ADMIN_AUTHORITIES.add(new TransferRatePermission(Integer.MAX_VALUE, Integer.MAX_VALUE));
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
public void init() throws FtpException {
mFTPServerFactory = new FtpServerFactory();
mListenerFactor = new ListenerFactory();
mListenerFactor.setPort(FTP_PORT);
//anonymous login
//seems no need
//ConnectionConfigFactory connectionConfigFactory = new ConnectionConfigFactory();
//connectionConfigFactory.setAnonymousLoginEnabled(true);
//mFTPServerFactory.setConnectionConfig(connectionConfigFactory.createConnectionConfig());
mFTPServerFactory.addListener(DEFAULT_LISTENER, mListenerFactor.createListener());
mFTPServerFactory.getFtplets().put(FTPLetImpl.class.getName(), new FTPLetImpl());
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
userManagerFactory.setFile(new File(ftpConfigDir + "users.properties"));
userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
mUserManager = userManagerFactory.createUserManager();
mFTPServerFactory.setUserManager(mUserManager);
this.createAdminUser();
SFTPServer.addUser("admin1", "123456", 20, 20);
//SFTPServer.addUser("gar", "gar", 100, 100);
//this works
//SFTPServer.addUser("anonymous", "", 20, 20);
mFTPServer = mFTPServerFactory.createServer();
mFTPServer.start();
}
private UserManager createAdminUser() throws FtpException {
UserManager userManager = mFTPServerFactory.getUserManager();
String adminName = userManager.getAdminName();
System.out.println(adminName);
if (!userManager.doesExist(adminName)) {
// LOG.info((new
// StringBuilder()).append("Creating user : ").append(adminName).toString());
BaseUser adminUser = new BaseUser();
adminUser.setName(adminName);
adminUser.setPassword(adminName);
adminUser.setEnabled(true);
adminUser.setAuthorities(ADMIN_AUTHORITIES);
adminUser.setHomeDirectory(DEFAULT_USER_DIR);
adminUser.setMaxIdleTime(0);
userManager.save(adminUser);
}
return userManager;
}
public static void addUser(String username, String password, int uploadRateKB, int downloadRateKB) throws FtpException {
BaseUser user = new BaseUser();
user.setName(username);
user.setPassword(password);
user.setHomeDirectory(DEFAULT_USER_DIR);
user.setEnabled(true);
//BaseUser anonuser = new BaseUser();
//anonuser = new BaseUser(user);
//anonuser.setName("anonymous");
List list = new ArrayList();
list.add(new TransferRatePermission(downloadRateKB * BYTES_PER_KB, uploadRateKB * BYTES_PER_KB)); // 20KB
list.add(new ConcurrentLoginPermission(MAX_CONCURRENT_LOGINS, MAX_CONCURRENT_LOGINS_PER_IP));
//write permission
//list.add(new WritePermission());
user.setAuthorities(list);
mFTPServerFactory.getUserManager().save(user);
}
public static void restartFTP() throws FtpException {
if (mFTPServer != null) {
mFTPServer.stop();
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
}
mFTPServer.start();
}
}
public static void stopFTP() throws FtpException {
if (mFTPServer != null) {
mFTPServer.stop();
System.out.println("server stoped");
}
}
public static void pauseFTP() throws FtpException {
if (mFTPServer != null) {
mFTPServer.suspend();
}
}
public static void resumeFTP() throws FtpException {
if (mFTPServer != null) {
mFTPServer.resume();
}
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
开始的时候不好使是因为没有写user类,实际上就没有添加user,即使拷贝了用户配置文件,所以仍旧无法访问;
现在也只是能添加用户,匿名登陆似乎不是十分完善,密码设为空时直接就能登录了。。。
package com.example.ftptest02;
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.ftplet.FtpException;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity {
public static String hostip;
private static String ftpConfigDir= Environment.getExternalStorageDirectory().getAbsolutePath()+"/ftpConfig/";
String state;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv=(TextView)findViewById(R.id.tvText);
String info="请通过浏览器或者我的电脑访问以下地址\n"+"ftp://"+getLocalIpAddress()+":2221\n";
hostip = getLocalIpAddress();
state = Environment.getExternalStorageState();
System.out.println(state.equals(Environment.MEDIA_MOUNTED));
System.out.println(Environment.getExternalStorageDirectory().getAbsolutePath());
System.out.println("hosip->>" + hostip);
tv.setText(info);
Runnable myRunnable = new MyRunnable();
Thread myThread = new Thread(myRunnable);
myThread.start();
}
class MyRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
File f=new File(ftpConfigDir);
if(!f.exists())
f.mkdir();
copyResourceFile(R.raw.users, ftpConfigDir + "users.properties");
try {
new SFTPServer().init();
} catch (FtpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("server is on");
}
}
public String getLocalIpAddress() {
String strIP=null;
try {
for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration 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();
}
}
}
}
}
这个layout比较简单,就不贴了,自己写一下就OK,连个按钮都不用。
直接用Android设备作为热点并实现FTP服务器也已经实现,过两天整理一下记录一下。