user3618833
user3618833

Reputation: 1

Building FTP Client from Scratch: Error "425 Can't open data connection for transfer"

I am trying to make an FTP client from scratch in Java.

I am using Filezilla as a server and I can connect to it up to a certain point. By that I mean that I have the Command port working, but no matter how much I search I cannot get the data port to connect.

All of the websites I've looked for say the problem has to do with the firewall and/or the router, however, when I try to connect to the server with the Filezilla client everything goes well.

What I have so far:

    serverSocket = new ServerSocket(20);
    socket = new Socket(127.0.0.1, 21);
    reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

    writer.write("USER " + Anonymous + "\n");
    writer.flush();
    writer.write("PASS " + "" + "\n");
    writer.flush();
    writer.write("PORT 127,0,0,1,0,14");
    writer.flush();
    writer.write("EPRT |1|127.0.0.1|20|");
    writer.flush()
    dataSocket = serverSocket.accept();

That logs me into the server and disconnects. To fix that I added an infinte while loop inside a thread (for the time being) until I can connect to the data port.

Upvotes: 0

Views: 2767

Answers (3)

user3618833
user3618833

Reputation: 1

I figured it out. The problem was that the server was trying to connect to a port and it wasn't the right one. What i decided to do was put the server in passive mode and connect to the socket that I saw. When it responded with this"227 Entering Passive Mode (127,0,0,1,194,16). The last two numbers are the port number. You have to turn to these decimals to hex and then take both hex numbers together to get the whole port number. On this case specifically 194 in decimal is equal to "C2" in hex, and 16 in decimal is equal to "10" in hex, with those two hex numbers combined you get "C210" which when you turn them back to decimal you get "49680" and that's the port number that you have to connect to.

  clientSocket = new Socket(127.0.0.1, 21);
  reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
  writer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

  writer.write("USER " + Anonymous + "\n");
  writer.flush();
  writer.write("PASS " + "" + "\n");
  writer.flush();
  writer.write("PASV");
  writer.flush()
  String testPort = scanner.nextLine(); //type in the number you get when you do math
                                        //in this case 49680
  socketServer = new Socket(host, Integer.parseInt(testPort));

That should connect the data port. Obviously this is not the final program, but its a proof of concept. Thank you for the people that helped out.

Upvotes: 0

user207421
user207421

Reputation: 310913

serverSocket = new ServerSocket(50222);

This creates a listening socket on port 50222.

writer.write("PORT 127,0,0,1,0,14");

This tells the server to connect to you on port 14.

Think about it.

Upvotes: 0

Steffen Ullrich
Steffen Ullrich

Reputation: 123320

While you do an accept on the (presumably) data socket socket2 you don't tell the server where this socket can be found, e.g. you did not issue a PORT or EPRT command before. Please have a deep look into the protocol documentation (mostly RFC959) before you attempt to implement the protocol.

Upvotes: 1

Related Questions