• Post Reply Bookmark Topic Watch Topic
  • New Topic

Using FTP Protocal and the LIST command

 
Jeff Holmes
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am using the source code at the bottom of this message, and everything is working fine for me. THe only problem, I have tried to implement the "LIST" command to the FTP server and I receive the following error:
425 Can't build data connection: Connection refused.
If any one can point me in the right direction I would appreciate it, I have also looked at the sun.net.FTP but I can't
find any documentation onm these api's. Thanks, Jeff
SOURCE CODE I HAVE AT CURRENT
import java.io.*;
import java.net.*;
import java.util.*;
public class FTPClient {
private boolean pauser = false; //Used for wait return
private static final int CNTRL_PORT = 21;
private Socket csock = null;
private Socket dsock = null;
private BufferedReader dcis;
private PrintWriter pos;

public FTPClient(String server, String user, String pass) {
try {
ftpConnect(server);
ftpLogin(user, pass);
} catch(IOException ioe) {
System.err.println("Failed with connection to Server");
}
}

private String responseParser(String resp) throws IOException {
if (resp.substring(0,1).equals("1")) {
pauser = true;
return(resp);
} else if (resp.substring(0,1).equals("2")) {
pauser = false;
return(resp);
} else if ((resp.substring(0,1).equals("3"))
| | (resp.substring(0,1).equals("4"))
| | (resp.substring(0,1).equals("5"))) {
return(resp);
} else {
return(null);
}
}

private void ftpLogout() {
try {
pos.print("BYE\r\n");
pos.flush();
pos.close();
dcis.close();
csock.close();
dsock.close();
} catch (IOException e) {
System.err.println("Error closing FTP: " + e.getMessage());
}
}

private String ftpSendCmd(String cmd) throws IOException {
if (pauser) {
if (dcis != null) {
String discard = dcis.readLine();
pauser = false;
}
}
pos.print(cmd + "\r\n");
pos.flush();
String response = responseHandler(cmd);
return(response);
}

private String responseHandler(String cmd) throws IOException {
String reply = this.responseParser(dcis.readLine());
String numerals = reply.substring(0,3);
String hyph_test = reply.substring(3,4);
String next = null;
if(hyph_test.equals("-")) {
String tester = numerals + " ";
boolean done = false;
while(!done) {
next = dcis.readLine();
while (next.equals("") | | next.equals(" ")) {
next = dcis.readLine();
}
if(next.substring(0,4).equals(tester))
done = true;
}
return next;
} else
return reply;
}

private Socket ftpGetDataSock() throws IOException {
String reply = ftpSendCmd("PASV");
StringTokenizer st = new StringTokenizer(reply, ",");
String[] parts = new String[6];
int i = 0;
while(st.hasMoreElements()) {
try {
parts[i] = st.nextToken();
i++;
} catch(NoSuchElementException nope){nope.printStackTrace();}
}
String[] possNum = new String[3];
for(int j = 0; j < 3; j++) {
possNum[j] = parts[0].substring(parts[0].length() - (j + 1),
parts[0].length() - j);
if(!Character.isDigit(possNum[j].charAt(0)))
possNum[j] = "";
}
parts[0] = possNum[2] + possNum[1] + possNum[0];
String[] porties = new String[3];
for(int k = 0; k < 3; k++) {
if((k + 1) <= parts[5].length())
porties[k] = parts[5].substring(k, k + 1);
else porties[k] = "FOOBAR";
if(!Character.isDigit(porties[k].charAt(0)))
porties[k] = "";
}
parts[5] = porties[0] + porties[1] + porties[2];
String ip = parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3];
int port = -1;
try {
int big = Integer.parseInt(parts[4]) << 8;
int small = Integer.parseInt(parts[5]);
port = big + small;
} catch(NumberFormatException nfe) {nfe.printStackTrace();}
if((ip != null) && (port != -1))
dsock = new Socket(ip, port);
else throw new IOException();
return dsock;
}

private void ftpSetTransferType(boolean asc) throws IOException {
String ftype = (asc? "A" : "I");
ftpSendCmd("TYPE "+ftype);
}

private void ftpConnect(String server) throws IOException {
csock = new Socket(server, CNTRL_PORT);
InputStream cis = csock.getInputStream();
dcis = new BufferedReader(new InputStreamReader(cis));
OutputStream cos = csock.getOutputStream();
pos = new PrintWriter(cos, true);
String numerals = responseHandler(null);
if(numerals.substring(0,3).equals("220")) ;
else System.err.println("Error connecting to ftp server.");
}
private void ftpLogin(String user, String pass)
throws IOException {
ftpSendCmd("USER "+user);
ftpSendCmd("PASS "+pass);
}
private void ftpSetDir(String dir)
throws IOException {
ftpSendCmd("CWD "+dir);
}

private String getAsString(InputStream is) {
int c=0;
char lineBuffer[]=new char[128], buf[]=lineBuffer;
int room= buf.length, offset=0;
try {
loop:
while (true) {
switch (c = is.read() ) {
case -1:
break loop;
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0,buf, 0, offset);
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
} catch(IOException ioe) {
System.err.println("Error in getAsStrig." + ioe.getMessage());
//ioe.printStackTrace();
}
if ((c == -1) && (offset == 0)) {
return null;
}
return String.copyValueOf(buf, 0, offset);
}

public String download(String dir, String file) throws IOException {
return download(dir, file, true);
}
public String download(String dir, String file, boolean asc) throws IOException {
ftpSetDir(dir);
ftpSetTransferType(asc);
dsock = ftpGetDataSock();
InputStream is = dsock.getInputStream();
ftpSendCmd("RETR "+file);
String contents = getAsString(is);
ftpLogout();
return contents;
}
public void append(String dir, String file, String what, boolean asc) throws IOException {
ftpSetDir(dir);
ftpSetTransferType(asc);
dsock = ftpGetDataSock();
OutputStream os = dsock.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
ftpSendCmd("APPE "+file);
dos.writeBytes(what);
dos.flush();
dos.close();
ftpLogout();
}
/**
* Transfer file to production box
* @param String remotedir
* @param String file
* @param String localdir
*/
public void upload(String remotedir, String file, String localdir, boolean asc) throws IOException {
//Check if file is OK
File ftpFile = new File(localdir + "\\" + file);
if (!ftpFile.isFile()) {
throw new IOException("FTP file does not exist.");
}
RandomAccessFile raf = new RandomAccessFile(ftpFile,"r");
ftpSetDir(remotedir);
ftpSetTransferType(asc);
dsock = ftpGetDataSock();
OutputStream os = dsock.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
ftpSendCmd("STOR "+file);
int idata = 0;
while (true) {
idata = raf.read();
if (idata != -1) {
dos.writeByte(idata);
} else {
break;
}
}
System.err.println("Done creating a file");
dos.flush();
dos.close();
ftpLogout();
}

public String delete(String dir, String File) throws IOException {
ftpSetDir(dir);
return(ftpSendCmd("DELE "+ File));
}
}
 
Carl Trusiak
Sheriff
Posts: 3341
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't see any code for LIST and I don't see how your using it from the calling program so, I can only speculate. In researching the RFC-959 on LIST I did find the following information.
LIST...The data transfer is over the data connection in type ASCII or type EBCDIC. (The user must ensure that the TYPE is appropriately ASCII or EBCDIC).
If the last operation you did set the connect for Binary transfer, it could be interferring with the ASCII transfer of data from the LIST command.
If this doesn't help, please post the LIST code and an example of how you are using it.

BTW nice start for an ftp client
[This message has been edited by Carl Trusiak (edited October 30, 2000).]
 
Jeff Holmes
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply and looking into this. The way I tried to implement the LIST command was by using the ftpSendCmd("LIST") method. As the return String I got '425 Can't build data connection: Connection refused.' Hope this can help in trying to determine what I have done wrong. Just can figure it out yet. Thanks again for looking at this. - Jeff
 
Carl Trusiak
Sheriff
Posts: 3341
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try doing a
ftpSetTransferType(true);
ftpSendCmd("LIST");
425 as written in RFC means unable to open the connection. If you have set the transfer type as binary, then the list command cannot establish a ascii connection with you to send the list information.
 
Jeff Holmes
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply, here is what I have in the method to try and get the LIST command to work:
public void list(String dir) throws IOException {
ftpSetDir(dir);
System.err.println(ftpSendCmd("PWD"));
System.err.println(ftpSendCmd("TYPE A"));
System.err.println(ftpSendCmd("LIST"));
}
And the output I receive from this method:
257 "/gw/prodn" is current directory.
200 Type set to A.
425 Can't build data connection: Connection refused.
Unfortunetly the changinf of the TYPE to ASCII didn't allow the connection either. Thanks for looking into this and any other ideas you have I would love to try. Still perplexed. Thanks, Jeff
 
Carl Trusiak
Sheriff
Posts: 3341
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
FOUND IT!!! LIST like RETR uses a new input stream. So...

Good Luck, and please keep me in mind when you complete this class
 
Jeff Holmes
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, I appreciate the effort to figure this out, and you won't be forgoten. Thanks again, Jeff
[This message has been edited by Jeff Holmes (edited November 01, 2000).]
 
amedeo cazzalini
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your work.
i'm using the FTPClient Class and the List Methods
they are very usefull for me.
thanks again
 
Savithri Devaraj
Ranch Hand
Posts: 103
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jeff Holmes:
Thanks, I appreciate the effort to figure this out, and you won't be forgoten. Thanks again, Jeff
[This message has been edited by Jeff Holmes (edited November 01, 2000).]

This is similar to what I am doing I am able to use the classes in Silverstream application server environment, but don't see any documentation.
Where is the documentation for the sun.net.ftp classes?
Carl, How are you interpreting the error messages??
Thanks in advance,
Savithri
 
Gorazd Hribar Rajteric
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Savithri!
Package sun.net.ftp is an implementation package for URLConnection and is not intended to be used directly. That is the reason why it is not documented.
Return codes are defined in RFCs for FTP protocol.
I have added the rename function. Here it is if anybody is interested:

Best regards,
Gorazd.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!