FtpClient Problem

hesk

Erfahrenes Mitglied
Hallo!

Ich downloade/uploade per ftp Bilder von einem FTP-Server.

Ich verwende hierfür: org.apache.commons.net.ftp.FTPClient

Aber an der Stelle(bei listFiles):

Code:
if (ftpClient.isConnected())
{
       serverFiles = ftpClient.listFiles(SERVER_DIR);
}

kommt folgende Exception:

Code:
java.net.SocketTimeoutException: connect timed out
	at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:337)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:198)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:157)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
	at java.net.Socket.connect(Socket.java:579)
	at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:726)
	at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2990)
	at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2965)
	at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2623)
	at xxx.xxx.objects.Ftp$UpdateTask.doInBackground(Ftp.java:292)
	at xxx.xxx.objects.Ftp$UpdateTask.doInBackground(Ftp.java:1)
	at org.jdesktop.swingworker.SwingWorker$1.call(Unknown Source)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at org.jdesktop.swingworker.SwingWorker.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)

Es tritt nicht immer auf, nur manchmal.
An was kann das liegen?

Im Verzeichnis was ich mir holen möchte liegen ca 5 Bilder mit jeweils 10KB.
Also die Größe kann es nicht sein.

Bitte um Hilfe:)
 
Wie schnell ist deine Verbindung zu dem Server (ping, SpeedTest)? Ist der Server vielleicht überlastet? Wan öffnest du die Verbindung? Vielleicht kann der Server die Verbindung nicht halten, d.h. wenn du ein Verzeichnis auflistest, ein bisschen wartest und dann noch mal ein Verzeichnis wartest, könnte die Wartezeit dazwischen das Problem sein.
 
Ich hab mit Ping:

Ping wird ausgeführt für xxx.xxx.xxx[xx.xx.xx.xxx] mit 32 Bytes Daten:
Antwort von xx.xx.xx.xxx: Bytes=32 Zeit=45ms TTL=54
Antwort von xx.xx.xx.xxx: Bytes=32 Zeit=46ms TTL=54
Antwort von xx.xx.xx.xxx: Bytes=32 Zeit=44ms TTL=54
Antwort von xx.xx.xx.xxx: Bytes=32 Zeit=45ms TTL=54

Ping-Statistik für xx.xx.xx.xxx:
Pakete: Gesendet = 4, Empfangen = 4, Verloren = 0
(0% Verlust),
Ca. Zeitangaben in Millisek.:
Minimum = 44ms, Maximum = 46ms, Mittelwert = 45ms


Der Server ist glaub ich nicht überlastet. Ist ein privater bei meinem Schwager.
Aber wie könnte ich überprüfen ob er überlastet ist?

Die Verbindung öffne ich 2 Zeilen vorher:
Code:
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setConnectTimeout(20000);
ftpClient.setDataTimeout(20000);

Ich öffne die Verbindung, hole mir das Verzeichnis vom Host und vergleiche es mit dem lokalen.
Dann werden gegebenfalls Bilder up bzw downgeloaded. Danach wird die Verbindung geschlossen.

Das ist der Update-Prozess der gleich beim Start des Programms gemacht wird.
 
Ich würde mal vermuten, dass das ein oder andere mal die Datei einfach zu groß ist und dementsprechend nicht in der Zeit (DataTimeout) heruntergeladen werden kann.
Das würde auch die nicht vorhandene Regelmäßigkeit erklären. :)
 
Zuletzt bearbeitet:
Die Dateien sind alle nicht größer als 15KB. Und es sind momentan ca 5 Stück dort.
Also die Größe kann es glaub ich nicht sein.
 
Java:
/**
     * Zum Server connecten
     * 
     * @param server
     * @return
     */
    private boolean connect()
    {
        ftpClient = new FTPClient();

        try
        {
            int reply;
            ftpClient.connect(SERVER_URL);

            // After connection attempt, you should check the reply code to verify success.
            reply = ftpClient.getReplyCode();

            if (!FTPReply.isPositiveCompletion(reply))
            {
                ftpClient.disconnect();
                ErrorDialog.show(new Exception("FTP server refused connection."));
            }
            else
            {
                return true;
            }
        }
        catch (IOException e)
        {
            if (ftpClient.isConnected())
            {
                try
                {
                    ftpClient.disconnect();
                }
                catch (IOException f)
                {
                    // do nothing
                }
            }

            ErrorDialog.show(e);
        }

        return false;
    }

Java:
 /**
     * Am Server anmelden
     * 
     * @param username
     * @param password
     */
    private void login()
    {
        try
        {
            if (!ftpClient.login(SERVER_USER, SERVER_PSW))
            {
                ftpClient.logout();
                ErrorDialog.show(new Exception("Username/Password falsch!"));
            }
            else
            {
                ftpClient.enterLocalPassiveMode();
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                ftpClient.setConnectTimeout(20000);
                ftpClient.setDataTimeout(20000);
            }
        }
        catch (IOException e)
        {
            ErrorDialog.show(e);
        }
    }

Java:
    /**
     * Task damit des Abgleichen der Dateien im Hintergrund passiert
     *
     * @author MaRk
     */
    private class UpdateTask extends Task<Void,Void> implements FinishListener
    {
        private Queue<Task<Void, Void>> taskQueue;
        private FinishListener finishListener;
        
        public UpdateTask()
        {
            super(Application.getInstance());
            taskQueue = new LinkedBlockingQueue<Task<Void, Void>>();
        }
        
        public void addFinishListener(FinishListener finishListener)
        {
            this.finishListener = finishListener;
        }
        
        @Override
        protected Void doInBackground() throws Exception
        {
            try
            {
                FTPFile[] serverFiles;
                
                if (ftpClient.isConnected())
                {
                    serverFiles = ftpClient.listFiles(SERVER_DIR);
                }
                else
                {
                    connect();
                    login();
                    serverFiles = ftpClient.listFiles(SERVER_DIR);
                }
                
                File[] hostFiles = new File(HOME_DIR).listFiles();

                List<String> uploadList = new ArrayList<String>();
                List<String> downloadList = new ArrayList<String>();

                // Listen befüllen

                for (FTPFile file : serverFiles)
                {
                    downloadList.add(file.getName());
                }

                for (File file : hostFiles)
                {
                    uploadList.add(file.getName());
                }

                // Listen reduzieren um die schon vorhandenen Dateien

                for (FTPFile file : serverFiles)
                {
                    if (uploadList.contains(file.getName()))
                    {
                        uploadList.remove(file.getName());
                    }
                }

                for (File file : hostFiles)
                {
                    if (downloadList.contains(file.getName()))
                    {
                        downloadList.remove(file.getName());
                    }
                }

                // Upload's + Download's zur Queue hinzufügen

                for (String file : uploadList)
                {
                    UploadTask uploadTask = new UploadTask(file);
                    uploadTask.addFinishListener(this);
                    taskQueue.add(uploadTask);
                }

                for (String file : downloadList)
                {
                    
                    DownloadTask downloadTask = new DownloadTask(file);
                    downloadTask.addFinishListener(this);
                    taskQueue.add(downloadTask);
                }
                
                // Queue starten
                finished("");
            }
            catch (IOException e)
            {
                ErrorDialog.show(e);
            }
            return null;
        }

        @Override
        public void finished(String threadName)
        {         
            Task<Void, Void> task;
            
            if( ( task = taskQueue.poll()) != null)
            {
                task.execute();
            }
            else
            {
                if (finishListener != null)
                {
                    finishListener.finished("update");
                }
            }
        }
        
        /**
         * Gibt die Anzahl der Task's zurück welche noch in der Queue sind.
         * @return
         */
        public int getQueueSize()
        {
            return taskQueue.size();
        }
    }

Java:
/**
     * Überprüft beide Verzeichnise(local + server) und gleicht diese ab.
     */
    public void update()
    {
        updateTask = new UpdateTask();
        updateTask.addFinishListener(this);
        updateTask.execute();
        updateFinished = false;
    }

Die letzte Methode (update()) wird am Programmstart ausgeführt. Im Konstruktor wird connect() + login() aufgerufen.
Der Fehler passiert bei:

Java:
if (ftpClient.isConnected())
{
     serverFiles = ftpClient.listFiles(SERVER_DIR);
}
 
Zuletzt bearbeitet:
Zurück