Search code examples
javaftpftpsapache-commons-net

"Connection refused" when connecting to FTP port 990 in Java


I made an array of FTPS clients and tried to connect it to the ip & port of my interest. Here is the code.

public class ftptest 
{   
    public static void delete_files(String path, int n) throws IOException
    {
        String realpath;
        for(int i=0 ; i<n ; i++)
        {
            realpath = path+i;
            File file = new File(realpath);
            FileUtils.cleanDirectory(file);
        }
    }

    public static void main(String[] args) throws Exception
    {
        int number = 1;
        String ip = "some_ip";
        int port = 990;

        FTPSClient[] client = new FTPSClient[number];

        System.out.println(ip);
        System.out.println("port = "+ port);


        for(int i = 0; i < number; i++)
        {
            String path = "D:\\ftptest\\client"+i;          
            File file = new File(path);
            file.mkdir();       


            client[i] = new FTPSClient(true);   
            client[i].setRemoteVerificationEnabled(false);
            client[i].setTrustManager
            (TrustManagerUtils.getAcceptAllTrustManager());         

            client[i].enterLocalPassiveMode();


            client[i].setControlEncoding("UTF-8");
            client[i].connect(ip,port);

            System.out.println("Connected to " + ip + ".");
        }   
    }
}

but somehow it fails in the client[i].connect(ip, port) part with the error

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 org.apache.commons.net.SocketClient.connect(SocketClient.java:182) at org.apache.commons.net.SocketClient.connect(SocketClient.java:203) at org.apache.commons.net.SocketClient.connect(SocketClient.java:296) at com.samsung.ftptest.ftptest.main(ftptest.java:66)

When it is FTP, not FTPS, it is working fine. Does anybody have any idea why it is not working?

Thank you.


Solution

  • The system on which you're running this, can't connect to port 990 on the server machine. There are a number of reasons this could be the case, including:

    • The server is not listening on port 990
    • A firewall is blocking port 990

    The first thing you should do is find a client that's successfully connecting to this server using FTPS, and check its configuration:

    • What port is it configured to use?
    • Is it using:
      • explicit FTPS (this is the preferred, standards-compliant way to do FTPS. It connects in plain FTP on port 21, then negotiates up to a secured protocol.
      • implicit FTPS (this approach has never been a standard, but does occur in the wild. Like HTTPS, a different port (often 990) is used, and an SSL handshakes happens immediately after connection)

    Once you know these things, you can put the right port and the right mode into your code.

    If you're certain of the port, and that it works from other machines, then a firewall is the likely culprit. Demonstrate that you can't connect, using telnet:

     unixprompt$ telnet serverhostname 990
    

    If it hangs, or says "Connection refused", you know that this machine can't reach it. If you get "Connected to ..." you know that at least you have TCP connectivity (then ctrl-] quit to get out).

    If you find that it's a firewall, be prepared for a battle. You're struggling with the control connection -- data connections are a whole new fight. Opening firewalls for passive mode explicit FTPS is fairly straightforward, and documented in this IETF draft: https://datatracker.ietf.org/doc/html/draft-fordh-ftp-ssl-firewall-00 -- but firewall admins are notoriously reluctant to do it.