Я использую Apache Commons Net (v3.5) с Java 8 для подключения к удаленному сайту FTPS (т.е. в Интернете). Я могу легко подключиться к клиенту FileZilla на своем компьютере с Windows 10, но моя программа Java не может выполнить те же действия. Я googled вверх и вниз, но не могу найти основную причину. Вот вещи, которые я подтвердил:
- Я убедился, что команды Java FTP находятся в том же порядке, что и клиент FileZilla.
- Я отключил брандмауэр Windows и антивирус на ПК
- Я повторно включил брандмауэр Windows и включил ведение журнала. При использовании FileZilla в журнале брандмауэра Windows указывается TCP-соединение, когда установлено соединение в пассивном режиме. Я не вижу такой записи с программой Java.
- Я установил сервер FileZilla на свой компьютер. Программа Java заработала после того, как я снял флажок «Требовать возобновления сеанса TLS при подключении данных при использовании PROT P». Исключение Java было другим, поэтому я не верю, что это дымящийся пистолет.
- Я успешно запустил этот же код на сервере test.rebex.com.
Ниже приведен код, и любые мысли приветствуются:
import java.io.IOException;
import java.io.PrintWriter;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
public class testProgram {
public static void main(String[] args) {
String ftpServer = "ftp.domain.com";
String ftpUsername = "[email protected]";
String ftpPassword = "********";
FTPSClient ftp = null;
// CONNECT TO THE SERVER
try {
// I have tried "SSL" as the argument, but same result
ftp = new FTPSClient();
ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
ftp.connect(ftpServer,21);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
System.err.println("---------->FTP server refused connection.\n");
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
// LOGIN INTO SERVER
try {
if (!ftp.login(ftpUsername, ftpPassword)) {
ftp.logout();
} else {
ftp.sendCommand("OPTS UTF8 ON");
ftp.execPBSZ(0);
ftp.execPROT("P");
ftp.pwd();
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
/* The next command always fails.
The FTP Server responds with "150 Accepted data connection" then:
org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:316)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:292)
at org.apache.commons.net.ftp.FTP.getReply(FTP.java:712)
at org.apache.commons.net.ftp.FTPClient.completePendingCommand(FTPClient.java:1857)
at org.apache.commons.net.ftp.FTPClient.listNames(FTPClient.java:2919)
at org.apache.commons.net.ftp.FTPClient.listNames(FTPClient.java:2952)
at myPackage.testProgram.main(testProgram.java:78)
I have tried other commands, but it disconnects here...
*/
FTPFile[] ftpFiles = ftp.listFiles();
System.out.println("---------->Number of Files = " + ftpFiles.length);
ftp.logout();
}
} catch (Exception e) {
e.printStackTrace();
}
//Ensure Disconnected at the end.
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException f) {
// do nothing
}
}
}
}
Вот журнал клиента FileZilla с моего ПК:
2016-09-06 09:09:50 4756 1 Status: Resolving address of ftp.domain.com
2016-09-06 09:09:51 4756 1 Status: Connecting to h1.h2.h3.h4:21...
2016-09-06 09:09:51 4756 1 Status: Connection established, waiting for welcome message...
2016-09-06 09:09:51 4756 1 Response: 220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
2016-09-06 09:09:51 4756 1 Response: 220-You are user number 2 of 50 allowed.
2016-09-06 09:09:51 4756 1 Response: 220-Local time is now 13:09. Server port: 21.
2016-09-06 09:09:51 4756 1 Response: 220-This is a private system - No anonymous login
2016-09-06 09:09:51 4756 1 Response: 220-IPv6 connections are also welcome on this server.
2016-09-06 09:09:51 4756 1 Response: 220 You will be disconnected after 15 minutes of inactivity.
2016-09-06 09:09:51 4756 1 Command: AUTH TLS
2016-09-06 09:09:51 4756 1 Response: 234 AUTH TLS OK.
2016-09-06 09:09:51 4756 1 Status: Initializing TLS...
2016-09-06 09:09:51 4756 1 Status: Verifying certificate...
2016-09-06 09:09:51 4756 1 Status: TLS connection established.
2016-09-06 09:09:51 4756 1 Command: USER [email protected]
2016-09-06 09:09:51 4756 1 Response: 331 User [email protected] OK. Password required
2016-09-06 09:09:51 4756 1 Command: PASS *************
2016-09-06 09:09:51 4756 1 Response: 230 OK. Current restricted directory is /
2016-09-06 09:09:51 4756 1 Command: SYST
2016-09-06 09:09:51 4756 1 Response: 215 UNIX Type: L8
2016-09-06 09:09:51 4756 1 Command: FEAT
2016-09-06 09:09:51 4756 1 Response: 211-Extensions supported:
2016-09-06 09:09:51 4756 1 Response: EPRT
2016-09-06 09:09:51 4756 1 Response: IDLE
2016-09-06 09:09:51 4756 1 Response: MDTM
2016-09-06 09:09:51 4756 1 Response: SIZE
2016-09-06 09:09:51 4756 1 Response: MFMT
2016-09-06 09:09:51 4756 1 Response: REST STREAM
2016-09-06 09:09:51 4756 1 Response: MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
2016-09-06 09:09:51 4756 1 Response: MLSD
2016-09-06 09:09:51 4756 1 Response: AUTH TLS
2016-09-06 09:09:51 4756 1 Response: PBSZ
2016-09-06 09:09:51 4756 1 Response: PROT
2016-09-06 09:09:51 4756 1 Response: UTF8
2016-09-06 09:09:51 4756 1 Response: TVFS
2016-09-06 09:09:51 4756 1 Response: ESTA
2016-09-06 09:09:51 4756 1 Response: PASV
2016-09-06 09:09:51 4756 1 Response: EPSV
2016-09-06 09:09:51 4756 1 Response: SPSV
2016-09-06 09:09:51 4756 1 Response: ESTP
2016-09-06 09:09:51 4756 1 Response: 211 End.
2016-09-06 09:09:51 4756 1 Command: OPTS UTF8 ON
2016-09-06 09:09:51 4756 1 Response: 200 OK, UTF-8 enabled
2016-09-06 09:09:51 4756 1 Command: PBSZ 0
2016-09-06 09:09:51 4756 1 Response: 200 PBSZ=0
2016-09-06 09:09:51 4756 1 Command: PROT P
2016-09-06 09:09:52 4756 1 Response: 200 Data protection level set to "private"
2016-09-06 09:09:52 4756 1 Status: Logged in
2016-09-06 09:09:52 4756 1 Status: Retrieving directory listing...
2016-09-06 09:09:52 4756 1 Command: PWD
2016-09-06 09:09:52 4756 1 Response: 257 "/" is your current location
2016-09-06 09:09:52 4756 1 Command: TYPE I
2016-09-06 09:09:52 4756 1 Response: 200 TYPE is now 8-bit binary
2016-09-06 09:09:52 4756 1 Command: PASV
2016-09-06 09:09:52 4756 1 Response: 227 Entering Passive Mode (h1,h2,h3,h4,133,150)
2016-09-06 09:09:52 4756 1 Command: MLSD
2016-09-06 09:09:52 4756 1 Response: 150 Accepted data connection
2016-09-06 09:09:52 4756 1 Response: 226-Options: -a -l
2016-09-06 09:09:52 4756 1 Response: 226 6 matches total
По совету Майка я включил отладку TLS. Похоже, программа снова проходит рукопожатие TLS. Вывод очень длинный, но после выполнения команды list я вижу «*** ClientHello, TLSv1.2» и что-то похожее на те же команды, что и при инициировании FTP-соединения.
Разница появляется в конце:
%% Cached client session: [Session-2, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
main, received EOFException: ignored
main, called closeInternal(false)
main, SEND TLSv1.2 ALERT: warning, description = close_notify
main, WRITE: TLSv1.2 Alert, length = 26
main, called closeSocket(false)
main, called close()
main, called closeInternal(true)
main, called close()
main, called closeInternal(true)
main, received EOFException: ignored
main, called closeInternal(false)
main, SEND TLSv1.2 ALERT: warning, description = close_notify
main, WRITE: TLSv1.2 Alert, length = 26
main, called closeSocket(false)
org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
Exception
, это смертельная ловушка. Кроме того, никогда не.printStackTrace()
; что это за польза? Закон об исключении - person fge   schedule 06.09.2016catch (Exception e)
. Это вовсе не карго-культовое программирование. Дело в том, что в этом блоке try одни инструкции могут выдать исключение, а другие нет. Следовательно: разделите и определите проблему. - person fge   schedule 06.09.2016