[Android]Android(安卓)FTP server based on Apache FTPServer
16lz
2021-12-26
老板让做的用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 {@Overridepublic void run() {// TODO Auto-generated method stubFile 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 blocke.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服务器也已经实现,过两天整理一下记录一下。
更多相关文章
- 'windowBackground' 无法找到问题
- 室内定位导航系统设计实现指南
- Android入门教程(四)之------Android工程目录结构介绍
- Android视频播放程序关键部分简要解析
- 升级Android(安卓)SDK后ADT找不到adb.exe文件的解决办法
- 如何使Android应用程序获取系统权限来修改系统时间
- 浅谈Java中Collections.sort对List排序的两种方法
- NPM 和webpack 的基础使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程