Ошибка «227 Вход в пассивный режим» / «Соединение отказано» при загрузке с локального FTP-сервера в эмуляторе Android - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь загрузить файл с локального сервера FileZilla с Java FTPSClient, запущенного в эмуляторе Android.

Я написал этот вспомогательный код для загрузки одного файла:

public boolean downloadSingleFile(FTPSClient ftpClient,
                                  String remoteFilePath, File downloadFile) {
    OutputStream outputStream;
    Log.i("t1", remoteFilePath + " - " + downloadFile.getAbsolutePath());
    try {
        outputStream = new BufferedOutputStream(new FileOutputStream(
                downloadFile));
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        boolean retval = ftpClient.retrieveFile(remoteFilePath, outputStream);
        outputStream.flush();
        return retval;
    } catch (Exception e) {
        Log.e("dwFile", e.toString());
        Log.e("dwFile", ftpClient.getReplyString());
    } return false;
}

Я вызываю эту функцию так:

FTPSClient dwClient = new FTPSClient();
dwClient.addProtocolCommandListener(
    new PrintCommandListener(
    new PrintWriter(new OutputStreamWriter(System.out, "UTF-8")), true));
dwClient.setConnectTimeout(30 * 1000);
dwClient.connect(OmsSettingsFunctions.getFTPServer());
Log.i("dwDB", dwClient.getReplyString());
if (dwClient.login(FPTuser, FTPpass))  {
    Log.i("dwDB", dwClient.getReplyString());
    dwClient.enterLocalPassiveMode();
    File dwFile = new File(externalPath + "/Android/data/com.myapp/files/Documents/db.temp");
    if(!downloadSingleFile(dwClient, "/DBs/db.txt", dwFile)) {
        Log.e("dwDB", "Download could not finish (DB)");
        Log.e("dwDB", dwClient.getReplyString());
    }...

Но я продолжаю получать эту ошибку:

I/System.out: 220-FileZilla Server version 0.9.41 beta
I/System.out: 220-written by Tim Kosse (Tim.Kosse@gmx.de)
              220 Please visit http://sourceforge.net/projects/filezilla/
I/System.out: AUTH TLS
D/EGL_emulation: eglMakeCurrent: 0xa209dd60: ver 3 0 (tinfo 0x9f652ff0)
D/EGL_emulation: eglMakeCurrent: 0xa209dd60: ver 3 0 (tinfo 0x9f652ff0)
I/System.out: 234 Using authentication type TLS
I/dwDB: 234 Using authentication type TLS
I/Permission: Readingpermission is granted
I/Permission: Writingpermission is granted
I/System.out: USER *******
I/System.out: 331 Password required for omstest
I/System.out: PASS *******
I/System.out: 230 Logged on
I/dwDB: 230 Logged on
I/t1: /DBs/db.txt - /storage/0FF0-280B/Android/data/com.myapp/files/Documents/db.temp
I/System.out: TYPE I
I/System.out: 200 Type set to I
I/System.out: PASV
I/System.out: 227 Entering Passive Mode (127,0,0,1,199,113)
E/dwFile: java.net.ConnectException: Connection refused
          227 Entering Passive Mode (127,0,0,1,199,113)
E/dwDB: Download could not finish (DB)
        227 Entering Passive Mode (127,0,0,1,199,113)

Я уже пытался использовать enterLocalActivemode() вместо enterLocalPassivmode(), но это не помогло. FTP-сервер работает по протоколу TLS и работает на моем локальном компьютере. Я подключаюсь к нему через 10.0.2.2 (Android loopback). Как я могу это исправить?

1 Ответ

0 голосов
/ 29 августа 2018

Хотя я не знаком с эмулятором Android, я предполагаю, что вам нужно подключиться к 10.0.2.2 для подключения к хост-машине эмулятора.

В пассивном режиме FTP сервер отправляет обратно IP-адрес, к которому FTP-клиент должен подключиться для передачи файла (или списка каталогов). Когда ваш FTP-сервер прослушивает 127.0.0.1, он отправляет обратно этот IP-адрес. Но 127.0.0.1 относится к (эмулированному) хосту Android в контексте вашего кода Android. Отсюда «соединение отказано».

Это очень похоже на обычную проблему с подключением к FTP-серверу за NAT. См. FTP-сервер, работающий на порте 2000 через NAT, не работает в пассивном режиме

И решение, следовательно, то же самое:

  • В интерфейсе сервера FileZilla выберите Редактировать> Настройки> Настройки пассивного режима> IPv4-специфичные> IP-адрес внешнего сервера для передачи в пассивном режиме . И введите 10.0.2.2.
  • Возможно, вам также придется снять отметку «Не использовать внешний IP для локальных подключений» .

Очевидно, что это в свою очередь делает сервер FTP непригодным для обычных клиентов.

И вы правильно прокомментировали, эта проблема возникает только при подключении из эмулятора Android к FTP-серверу, работающему на хосте эмулятора.

...