Bab
Bab

Reputation: 443

Can't transfer a file with a binary transfer with a FTP client

Have this FTP client where I transfer files with byte array. In the console it says Successfully transferred but it doesn't transfer anything and I get these errors:

Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at ftp.ftp.connect(ftp.java:110)
at ftp.test.main(test.java:12)

I want files to be tranferred to this filepath: c:/Users/username/Desktop/FTP

This is my program:

package ftp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;

public class ftp
{
public synchronized void connect(String host, int port, String user,
        String pass) throws IOException {
    Socket socket = new Socket(host, port);
    //  if (socket != null) {
    //     throw new IOException("SimpleFTP is already connected. Disconnect first.");
    //   }
    //  socket = new Socket(host, port);
    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    BufferedWriter writer = new BufferedWriter(
            new OutputStreamWriter(socket.getOutputStream()));


    String response = reader.readLine();

    if (!response.startsWith("220-")) {
        throw new IOException(
                "FTP modtog et ukendt svar, da den blev forbundet til FTP server: "
                        + response);
    } else {System.out.println("1:"+response);
    response = reader.readLine();
    System.out.println("1:"+response);
    response = reader.readLine();
    System.out.println("1:"+response);


    }
    writer.write("user geek"+"\r\n");
    writer.flush();
    response= reader.readLine();
    System.out.println("2"+response);
    // response = reader.readLine();
    /*  if (!response.startsWith("331 ")) {
          throw new IOException(
              "SimpleFTP received an unknown response after sending the user: "
                  + response);
        }
        else {*/
    writer.write("PASS hello" +"\r\n");
    writer.flush();
    response= reader.readLine();
    System.out.println("3"+response);
    //}


    //response = reader.readLine();
    /*if (!response.startsWith("230 ")) {
          throw new IOException(
              "SimpleFTP was unable to log in with the supplied password: "
                  + response);
        }
        else {*/
    //System.out.println("4"+response);
    //}

    writer.write("pasv"+"\r\n");
    writer.flush();
    response= reader.readLine();
    System.out.println("5"+response );
    String [] r=response.trim().split(",");

    String reg=r[4];
    String add= r[5].replace(")", "");
    int m = Integer.parseInt(reg);
    int a = Integer.parseInt(add);

    int port1 = m*256+a;
    System.out.println(port1);
    Socket datasocket = new Socket("127.0.0.1", port1);
    writer.write("type A\r\n");
    writer.flush();
    response= reader.readLine();
    System.out.println("6"+response);
    BufferedReader reader2 = new BufferedReader(new InputStreamReader(datasocket.getInputStream()));


    writer.write("LIST\r\n");
    writer.flush();
    response= reader.readLine();
    System.out.println("7"+response);


    String text;
    while((text =reader2.readLine())!=null){
        System.out.println(text);

        writer.write("RETR\r\n");
        writer.flush();
        response= reader.readLine();
        System.out.println("8"+response);

        Socket filsocket = new Socket ("localhost", port1);
        InputStream is = null;
        FileOutputStream fos = null;

        byte[] mybytearray = new byte[1024];
        try {
            is = filsocket.getInputStream();
            fos = new FileOutputStream("myfile.txt");

            int count;
            while ((count = is.read(mybytearray)) >= 0) {
                fos.write(mybytearray, 0, count);
            }
        } finally {
            fos.close();
            is.close();
            filsocket.close();
        }

    }


}       

}

Output:

1:220-FileZilla Server version 0.9.50 beta
1:220-written by Tim Kosse ([email protected])
1:220 Please visit https://filezilla-project.org/
2331 Password required for geek
3230 Logged on
5227 Entering Passive Mode (127,0,0,1,219,100)
6200 Type set to A
7150 Opening data channel for directory listing of "/"
-rw-r--r-- 1 ftp ftp              0 Apr 14 20:18 abc.txt
8226 Successfully transferred "/"
Exception in thread "main" java.net.ConnectException: Connection refused:   connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at ftp.ftp.connect(ftp.java:112)
at ftp.test.main(test.java:12)

Upvotes: 0

Views: 868

Answers (1)

Dave
Dave

Reputation: 373

Ok. There are a number of issues to fix here. First, every time you need to get data over the data channel (using that arbitrary high port you're calculating from the passive response), you need to issue another PASV command and open a new socket using that new port.

Try this, code, starting with the LIST command:

writer.write("LIST\r\n");
writer.flush();
response = reader.readLine();
System.out.println("7" + response);

List<String> files = new ArrayList<>();
String text;
while ((text = reader2.readLine()) != null) {
    String filename = parseFilename(text);
    files.add(filename);
}
reader2.close();
datasocket.close();
reader.readLine();

for (String file : files) {
    int passivePort = getPort(reader, writer);
    writer.write("RETR test.txt\r\n");
    writer.flush();
    System.out.println(response);
     byte[] mybytearray = new byte[1024];
    // try-with-resources
    try (Socket filesocket = new Socket("localhost", passivePort);
         InputStream is = filesocket.getInputStream();
         FileOutputStream fos = new FileOutputStream("c:\\temp\\" + file)) {
         int count;
         while ((count = is.read(mybytearray)) >= 0) {
             fos.write(mybytearray, 0, count);
         }
    }
}

getPort then, of course, looks like this:

private int getPort(BufferedReader reader, BufferedWriter writer) throws IOException {
    String response;
    writer.write("PASV" + "\r\n");
    writer.flush();
    response = reader.readLine();
    System.out.println("5" + response);
    String[] r = response.trim().split(",");

    String reg = r[4];
    String add = r[5].replace(")", "");
    int m = Integer.parseInt(reg);
    int a = Integer.parseInt(add);

    return m * 256 + a;
}

I'll let you write parseFilename; that's just a matter of pulling the filename from the raw listing returned by the server.

This code should do the trick for you, and worked for me against a local Apache FTP server. Since you're using Filezilla, you may need to read in an extra line somewhere if they're returning more data than my server was -- but otherwise this could should work for you.

Upvotes: 1

Related Questions