I am new to FTP. I have a problem with my FTPSClient program. Only control channel is encrypted. I need both the control and data channel to be encrypted.
public boolean login(String usrName,char[] passwd){
try {
ftpClient = new FTPSClient(protocol,false); // SSL FTP
ftpClient.connect(strHost);
int reply = ftpClient.getReplyCode(); // After connection attempt, you should check the reply code to verify success.
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
log.error("FTP server refused connection.");
return false;
}
ftpClient.setBufferSize(1000);
if (!ftpClient.login(strUsrName,new String(passwd))){
ftpClient.logout();
bLoginStatus = false;
return false;
}
else
bLoginStatus = true;
if(iMode == LOCAL_ACTIVE_MODE)
ftpClient.enterLocalActiveMode();
else if(iMode == LOCAL_PASSIVE_MODE)
ftpClient.enterLocalPassiveMode();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch(Throwable t){
t.printStackTrace();
}finally {
if (bLoginStatus == false && ftpClient.isConnected()){
try{
ftpClient.disconnect();
}
catch (IOException f){
// do nothing
}
}
}
if(ftpClient.isConnected())
return true;
else
return false;
}
You need to tell the client to also encrypt the data connection, you can do this (if i recall correctly) with the PROT command:
client.execPBSZ(0);
client.execPROT("P");
Related
I have a backup process by FTP, it works with org.apache.commons.net.ftp.FTPClient library.
I found that some file are partially uploaded and I did not found any upload error, sometimes just retrying I solved the problem.
This is my FTP connection code, I'm using passive mode and keepalive:
public FTPClient ftpConnect(){
FTPClient ftp = new FTPClient();
int retries=3;
int timeout=5000;
URL url;
try {
url = new URL(REMOTE_URL);
if(!url.getProtocol().equals("ftp"))
throw new MalformedURLException();
} catch (MalformedURLException e1) {
throw new SystemException("Invalid protocol");
}
ftp.setConnectTimeout(timeout);
ftp.setDataTimeout(timeout);
for (int i = 1; i <= retries; i++) {
try {
ftp.connect(url.getHost(),url.getPort()>0?url.getPort():21);
ftp.setSoTimeout(timeout);
ftp.enterLocalPassiveMode();
ftp.setKeepAlive(true);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
throw new ConnectException("FTP server refused connection");
}
if(StringUtils.isNotBlank(url.getUserInfo())){
String[] arr=URLDecoder.decode(url.getUserInfo(), "UTF-8").split(":");
String user=arr[0];
String pass=arr.length>0?arr[1]:"";
if (!ftp.login(user,pass)) {
ftp.logout();
throw new SecurityException("FTP server login not valid");
}
}
ftp.changeWorkingDirectory(url.getPath());
break;
} catch (SocketException e ) {
log.error("Socket Error, retry nr {}",i);
if(i==retries) throw new SystemException("Socket error, max retries reached");
} catch (IOException e) {
throw new SystemException("Connection Error");
} catch (SecurityException e) {
throw new SystemException("Invalid authentication");
}
}
return ftp;
}
I would like to know how cand I solve this partial upload and above all how can I get an error in these cases.
I coded a server application that constantly listens to data being sent to it. I took multi-threading into consideration by the way. I have the main thread, writer thread, and reader thread. When I launch the program, everything works perfectly. After about 15 minutes of up-time though, my CPU usage just randomly skyrockets. I believe it reaches about 40% just for the server application if I remember correctly. I think I'm doing something wrong with networking since this is my first time working with sockets.
This is what I use to read data:
public void run(){
Socket s = null;
InputStream in = null;
while (Main.running){
try {
s = network.getServerSocket().accept();
in = s.getInputStream();
} catch (IOException e){
e.printStackTrace();
}
if (in != null){
DataInputStream input = new DataInputStream(in);
try {
while (input.available() != -1) {
byte type = input.readByte();
PacketIn packet = Utils.getPacket(main, type);
packet.readData(input);
if (packet instanceof PacketInLogin) {
PacketInLogin login = (PacketInLogin) packet;
login.setSocket(s);
String server = login.getServer();
Socket socket = login.getSocket();
Main.log("Login request from server: '" + server + "'. Authenticating...");
boolean auth = login.authenticate();
Main.log("Authentication test for server: '" + server + "' = " + (auth ? "PASSED" : "FAILED"));
if (auth) {
main.getServers().put(server, new DataBridgeServer(main, server, socket));
}
main.getTransmitter().sendPacket(new PacketOutAuthResult(main, auth), socket);
} else if (packet instanceof PacketInDisconnect) {
PacketInDisconnect disconnect = (PacketInDisconnect) packet;
main.getServers().remove(disconnect.getServer().getName());
Main.log("'" + disconnect.getServer().getName() + "' has disconnected from network.");
}
}
} catch (IOException e){
if (!(e instanceof EOFException)){
e.printStackTrace();
}
} finally {
if (in != null){
try {
in.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
}
try {
if (s != null) s.close();
if (in != null) in.close();
} catch (IOException e){
e.printStackTrace();
}
}
This is what I use to write data (to the client. This code is still part of the server):
public void run(){
while (Main.running){
if (!QUEUED.isEmpty()){
PacketOut packet = (PacketOut) QUEUED.keySet().toArray()[0];
Socket server = QUEUED.get(packet);
DataOutputStream out = null;
try {
out = new DataOutputStream(server.getOutputStream());
packet.send(out);
} catch (IOException e){
e.printStackTrace();
} finally {
if (out != null){
try {
out.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
QUEUED.remove(packet);
}
}
}
Here is my simple code:
public boolean sendCSV() throws IOException {
System.out.println("Translating from xls to csv...");
File xls = new File("file.xls");
File csvFile;
csvFile = CSVManager.xlsToCsv(xls);
csvFile.renameTo(new File("file.csv"));
FTPClient client = new FTPClient();
FileInputStream fis = null;
try {
System.out.println("Establishing connection...");
client.connect(ftpHost, ftpPort);
System.out.print(client.getReplyString());
System.out.println("Connection ok.");
if (client.login(ftpUser, ftpPass)) {
System.out.println("Login ok");
System.out.print(client.getReplyString());
System.out.println("Setting PASV");
client.enterLocalPassiveMode();
System.out.print(client.getReplyString());
if (client.changeWorkingDirectory("/MYDIR")) {
System.out.println("Dir changed");
System.out.print(client.getReplyString());
} else {
System.out.println("Error changing dir");
System.out.print(client.getReplyString());
}
String filename = csvFile.getName();
TrayIconManager.SwitchTrayToFull();
fis = new FileInputStream(filename);
if (client.storeFile(filename, fis)) {
System.out.println("File sent");
System.out.print(client.getReplyString());
} else {
System.out.println("Error during sending file");
System.out.print(client.getReplyString());
}
}
if (client.logout()) {
System.out.println("Logout ok");
System.out.print(client.getReplyString());
return true;
} else {
System.out.println("Logout problem");
System.out.print(client.getReplyString());
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
if (fis != null) {
fis.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
What is the problem? The output says that
File sent
226-29 Kbytes used (0%) - authorized: 512000 Kb
226-File successfully transferred
226 0.343 seconds (measured here), 30.59 Kbytes per second
but is not true, because once I check on the ftp server the file is not there!
Why Kbytes used is 0%? Maybe is that the error?
The code seems to be ok, also the output.
So what is the real problem?
When i try to list files from my location using ftpClient.listFiles("folder"); it shows
org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array.
Can some one guide me what i am doing wrong.
I use apache-commons-net-3.3
My code is
FTPClientConfig ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_NT);
FTPClient ftpClient = new FTPClient();
ftpClient.configure(ftpClientConfig);
ftpClient.connect(hostName, Integer.valueOf(portNumber));
ftpClient.enterLocalPassiveMode();
ftpClient.login(username, password);
// Error throws here
FTPFile[] files = ftpClient.listFiles("folder");
This Exception is thrown when a user gave a Wrong or Encrypted Username Or Password.
Apache is not throwing the correct exception.
public void ConnectToFtp(String serverAdd,String username,String password){
try {
ftpclient.connect(serverAdd);
boolean login = ftpclient.login(username,password);
reply = ftpclient.getReplyCode();
if(FTPReply.isPositiveCompletion(reply)){
System.out.println("Connected Success");
}else {
System.out.println("Connection Failed");
ftpclient.disconnect();
}
if (login) {
System.out.println("Connection established...");
FTPFile[] ftpFiles = ftpclient.listFiles();
for (FTPFile ftpFile : ftpFiles) {
if (ftpFile.getType() == FTPFile.DIRECTORY_TYPE) {
System.out.printf("FTPFile: %s; %s%n",
ftpFile.getName(),
FileUtils.byteCountToDisplaySize(ftpFile.getSize()));
}
}
}
boolean logout = ftpclient.logout();
if (logout) {
System.out.println("Connection close...");
} else {
System.out.println("Connection fail...");
}
} catch (SocketException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
ftpclient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Following is my java function to write a csv file in ftp location.The file gets created to ftp location but the file size is 0 bytes and file is empty.Kindly help as I am stuck
public int WriteFileToFtp(String FileName, String FileData) {
//get these details for the version??
//??
FTPClient ftp= new FTPClient();
try {
InputStream is = new ByteArrayInputStream(FileData.getBytes("ISO-8859-1"));
ftp.connect(ftpIP);
boolean isConnection = ftp.login(userName,password);
if(!isConnection){
logger.error("Connection failed");
return -1;
}
ftp.enterLocalActiveMode();
ftp.setFileType(FTP.BINARY_FILE_TYPE);//setting fileType
//?? go to directory using the circle code
if(ftpDirectoryToBeUpdate!=null && ftpDirectoryToBeUpdate.trim().length()>0)
{
logger.error("Changing directory for write="+ftpDirectoryToBeUpdate+" lcd="+ftp.printWorkingDirectory());
ftp.changeWorkingDirectory(ftpDirectoryToBeUpdate);
logger.error("Changed directory for write="+ftpDirectoryToBeUpdate+" lcd="+ftp.printWorkingDirectory());
}else
{
logger.error("Changed directory for write failed lcd="+ftp.printWorkingDirectory());
logger.error("DirectoryToReadFrom="+ftpDirectoryToBeUpdate);
}
ftp.storeFile(FileName,is) ;
logger.error(ftp.getReplyString());
is.close();
if(ftp.isConnected())
ftp.disconnect();
} catch (SocketException e) {
//logger.error(LoggerKeyWord.ERROR_ALERT + " FTP WRITE ERROR");
logger.error(e,e);
e.printStackTrace();
return -1;
} catch (IOException e) {
// logger.error(LoggerKeyWord.ERROR_ALERT + " FTP WRITE ERROR");
logger.error(e,e);
e.printStackTrace();
return -1;
}
try {
if(ftp.isConnected())
ftp.disconnect();
} catch (IOException e) {
logger.error (e,e);
e.printStackTrace();
return -1;
}
return 1;
}
have you tried closing input stream before saving the file?