I am trying to implement an ftpClient interface which would be able to manage network connection issues. I am using the ftp4j library for this purpose.
I can succesfully upload files BUT i have some issues when a connection failure appears during a file upload process. I would like to be able to re-upload (not append, just start again) the file just after a connection issue terminate my previous upload attempt.
The case is that if i try to re-try uploading the file some seconds or even minutes after the previous unsuccesful attemp i am getting:
it.sauronsoftware.ftp4j.FTPException [code=550, message= Access is denied. ]
at it.sauronsoftware.ftp4j.FTPClient.upload(FTPClient.java:2794)
at it.sauronsoftware.ftp4j.FTPClient.upload(FTPClient.java:2586)
If i wait some time and then re-try, i will be able to upload the file to the FTP server.
Is it some parameter that i could set to my ftpClient:
...
FTPClient client = new FTPClient();
try {
client.setType(FTPClient.TYPE_BINARY);
client.connect(ipAddress, port);
client.login(userName, password);
System.out.println("Connected to FTP Server!");
...
}
...
if(ftpClient.isResumeSupported()) {
System.err.println("FTP Server supports resume. Trying to upload file");
ftpClient.upload(localFile, writtenBytes, new Ftp4jListener());
} else {
System.err.println("FTP Server does NOT supports resume. Trying to upload file");
ftpClient.upload(localFile, new Ftp4jListener());
}
...
for being able to overcome this "Access is denied" problem?
Any ideas what is it causing such an exception? Maybee a server parameter?
Related
I try to connect to FTP server in ESP8266. Connection is successful, but I can't get list of files on the server.
My code is:
FTPClient mFtpClient = new FTPClient();
mFtpClient.setConnectTimeout(10000);
mFtpClient.connect(InetAddress.getByName(ip));
status = mFtpClient.login(userName, pass);
Log.e("isFTPConnected", String.valueOf(status));
if (FTPReply.isPositiveCompletion(mFtpClient.getReplyCode())) {
mFtpClient.setFileType(FTP.BINARY_FILE_TYPE);
mFtpClient.enterLocalPassiveMode();
FTPFile[] mFileArray = mFtpClient.listFiles();
Log.e("Size", String.valueOf(mFileArray.length));
}
In logical I get the error :
java.io.IOException: Unable to determine system type - response: 500 Unknow command.
I use Apache Commons Net FTP library. So what is wrong in my code? From FileZilla Windows client, I can connect. May be the reason is that in ESP is SPIFF file system? Or another one reason?
Thanks for answers, and interest!
Your server does not support SYST command, that the FTPClient needs to decide how to parse a response of LIST command.
Solutions are:
If your server supports MLSD command, use mlistDir instead of listFiles.
Or use System.setProperty to set FTP_SYSTEM_TYPE_DEFAULT or FTP_SYSTEM_TYPE to suggest what directory listing format your server is using.
With my Java-Program I'm connecting to a FTP server with Apache Commons Net.
The FTP server works as the update server for my software and currently everytime I check for updates, the updater downloads a .txt and checks if the version number written in the file is greater than the version number currently installed on the machine.
Is there a way to get the version number of the update for the software on the machine from the welcome-message of the FTP server?
Then I don't have to download the .txt to check for updates instead I'm able to only connect to the server and check the welcome-message for the number?
The welcome message is effectively a "response" to a connection.
So after you connect using the FTPClient.connect(), use the FTPClient.getReplyStrings() to retrieve the welcome message.
ftp.connect(server);
// After connection attempt, you should check the reply code to verify success.
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
{
ftp.disconnect();
System.err.println("FTP server refused connection.");
System.exit(1);
}
// read the initial response (aka "Welcome message")
String[] welcomeMessage = ftp.getReplyStrings();
I have a straightforward program that uploads a file to a FTP server.
This works when I'm not on a VPN (Hotspot Shield).
FTPClient ftp = new FTPClient();
ftp.connect(ftpServer);
ftp.login(log,pw);
ftp.changeWorkingDirectory(dir);
File f = new File(FileName);
final InputStream is = new FileInputStream(f.getPath());
ftp.storeFile(f.getName(), is);
ftp.disconnect();
is.close();
However, when I am connected to a VPN, it runs with no errors and doesn't throw any exceptions, but the file just doesn't get uploaded.
I've tried to FTP via command window,
and when I try to mput it gives me this error:
"I won't open a connection to 'random ip address' (ony to 'another
random ip')
So now I think this is some kind of FTP restriction problem with VPN?
Anybody have any kind of experience with this?
Thanks.
EDIT:
I found a solution,
calling ftp.enterLocalPassiveMode(); before I storeFile() seems to have resolve the error.
I found a solution, calling ftp.enterLocalPassiveMode(); before I storeFile() seems to have resolve the error.
I am using ftp4j library to implement my FTP clients however a server that I am trying to connect accept connections only in active mode.
So when I am trying to list remote files i am getting:
ERROR : Error in Connecting to Remote Machine... Hence exitting...
it.sauronsoftware.ftp4j.FTPException [code=501, message= Server cannot accept argument.]
at it.sauronsoftware.ftp4j.FTPClient.openActiveDataTransferChannel(FTPClient.java:3600)
at it.sauronsoftware.ftp4j.FTPClient.openDataTransferChannel(FTPClient.java:3551)
at it.sauronsoftware.ftp4j.FTPClient.listNames(FTPClient.java:2335)
at com.npap.network.TranferFileFtp4j.listRemoteFilesFtp1(TranferFileFtp4j.java:999)
Here is the code:
...
//connect to server method - in active mode!
ftpClient = Ftp4jUtility.connect1(SERVER_MACHINE, PORT, SERVER_USERNAME, SERVER_PASSWORD);
try {
ftpClient.changeDirectory(config.getFtpRemoteFolderReports());
log.info("Changed directory to: " + config.getFtpRemoteFolderReports());
} catch (FTPException | FTPIllegalReplyException | IOException | IllegalStateException e) {
e.printStackTrace();
}
String[] filesList = ftpClient.listNames();
for(String f: filesList) {
log.info("fetched file: " + f);
tmpAllRemoteFiles.add(f);
}
Any way to list remote files when connecting in active mode?
Yes, you can use the .listNames() in the active mode.
The problem is likely that the server cannot connect back to your client to open the data connection. You have to open the ports from FTP data connection range on your local firewall (if any), as well as route the incoming connections on your NAT (if any).
Configuring the active mode FTP is cumbersome and is rarely used.
Learn (my) article about required network configuration in respect to FTP active mode.
The 501 error code comes from the FTP server (IIS likely). You will find lots of similar problems, if you google for "501 Server cannot accept argument".
There's nothing wrong with your code. It's either the network configuration or server-side problem.
I am trying to use apache commons to send manual FTP commands as I have to send non-standard FTP commands to a specific server (that accepts them)
Before I try to send these non-standard commands I want to get FTP working manually with commons.net.ftp. Unfortunately I seem to be missing something.
This works fine (i.e. it retrieves the list of files)
FTPClient ftp = new FTPClient();
FTPClientConfig config = new FTPClientConfig();
ftp.configure(config);
ftp.connect("ftp.mozilla.org");
ftp.login("anonymous", "");
ftp.enterLocalPassiveMode();
FTPFile[] fileList = ftp.listFiles("/");
This doesn't
FTPClient ftp = new FTPClient();
FTPClientConfig config = new FTPClientConfig();
ftp.configure(config);
ftp.connect("ftp.mozilla.org");
ftp.login("anonymous", "");
ftp.sendCommand("PASV");
ftp.sendCommand("NLST");
I get the appropriate response for ftp.sendCommand("PASV"); but it times out on ftp.sendCommand("NLST"); finally giving me
425 Failed to establish connection.
I have tried to research the topic but most advice on this error is for people setting up servers (and it's usually a firewall problem).
Why does it work when net.ftp does it, but not when I send the commands manually?
Sending the PASV command manually is not enough, the client has to open the data connection to the port specified by the server in response to the PASV command. This is performed by calling the enterLocalPassiveMode() method. Since sending PASV manually doesn't initialize the data connection you get an error shortly after.
See http://slacksite.com/other/ftp.html#passive for more details on the FTP protocol.