Android系统-Ftp服务器实现

320 阅读2分钟

本文主要介绍工作中接触的两个实现方法

1.tcpsvdftpd实现

条件:需要/system/bin/tcpsvd和/system/bin/ftpd,以及设备具有root权限

busybox tcpsvd 0 21 busybox ftpd -w /mnt/sdcard/Android/data/com.sujue.home/files/Ftp&
// tcpsvd就是/system/bin/tcpsvd,ftpd就是/system/bin/ftpd
// 上面的0表示对所有ip地址都进行侦听
// 21表示ftp服务器的默认端口
// -w /mnt/sdcard/Android/data/com.sujue.home/files/Ftp
// 表示对/mnt/sdcard/Android/data/com.sujue.home/files/Ftp具有写权限
// &表示以后台服务运行

以上创建的ftp服务器是匿名登陆的。

2.应用层实现Ftp服务器

2.1 添加依赖

mina.apache.org/ftpserver-p… 下载(选择合适版本下载)

image.png

解压后在lib中找出下列jar包,添加到Android项目的lib下。 image.png

build.gradle文件中添加

image.png

在AndroidManifest.xml中声明权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

如果编译报错中

image.png 解决:在build.gradle文件中加如下代码

android {
    ...
    ...
    ...
    ```
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
    }

}

2.2实现

以下是一个demo

public class FtpService extends Service {
    private FtpServer server;
    private static String rootPath;
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //Ftp 共享目录
        rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        try {
            init();
            Toast.makeText(this, "启动ftp服务成功", Toast.LENGTH_SHORT).show();
        } catch (FtpException e) {
            e.printStackTrace();
            Toast.makeText(this, "启动ftp服务失败", Toast.LENGTH_SHORT).show();
        }
    }

    public void init() throws FtpException {
        stopFtp();
        startFtp();
    }
    
    private void stopFtp() {
        if (server != null) {
            server.stop();
            server = null;
        }
    }
    private void startFtp() throws FtpException {
        boolean isAnonymous = true; //是否匿名
        String userName = "admin";
        String password = "123456";
        int port = 2121;
        List<Authority> authorities = new ArrayList<Authority>();
        authorities.add(new WritePermission());
        FtpServerFactory serverFactory = new FtpServerFactory();

        //设置访问用户名和密码还有共享路径
        BaseUser baseUser = new BaseUser();
        if(isAnonymous) {
            //设置这个anonymous用户后只要有不输密码的都能访问ftp服务器
            baseUser.setName("anonymous");
            baseUser.setHomeDirectory(rootPath);
            baseUser.setAuthorities(authorities);
            serverFactory.getUserManager().save(baseUser);
        }
        baseUser = new BaseUser();
        baseUser.setName(userName);
        baseUser.setPassword(password);
        baseUser.setHomeDirectory(rootPath);
        baseUser.setAuthorities(authorities);
        serverFactory.getUserManager().save(baseUser);


        ListenerFactory factory = new ListenerFactory();
        Log.e("sujue",port+":"+rootPath);
        factory.setPort(port);
        //factory.setServerAddress("192.168.42.129");
        serverFactory.addListener("default", factory.createListener());

        server = serverFactory.createServer();
        server.start();
    }

}

2.3 注意点

  1. 可以自定义一个UserManager来实现自己的认知机制
  2. 没有特别的要求可以设置ip就不设置ip,网上很多demo都会设置,其实没必要。 上面中一开始是设置了IP的,该ip是我所用设备type-c对应的网卡ip,通过type-c连接来进行tcp通信。但是当验证断点续传时拔插type-c会引发,ftp服务器监听断开。