2012-04-09 7 views
0

Вот несколько бит кода, который я использую для загрузки через ftp. Я пытался остановить загрузку, затем продолжить или снова загрузить ее. Я пробовал ftp.abort(), но он зависает только и возвращает таймаут.Как остановить ftp от загрузки в python?

ftplib.error_proto: 421 Data timeout. Reconnect. Sorry. 

СЦЕНАРИЙ: Сценарий пользователь выберет файл для загрузки, во время загрузки, пользователь может остановить текущую загрузку и загрузить новый файл. Код 'if os.path.getsize (self.file_path)> 117625:' является только моим примером, если пользователь останавливает загрузку. Это не полный размер файла.

спасибо.

from ftplib import FTP 

class ftpness: 

    def __init__(self): 
      self.connect(myhost, myusername, mypassword) 

    def handleDownload(self,block): 
     self.f.write(block) 
     if os.path.getsize(self.file_path) >117625: 
       self.ftp.abort() 

    def connect(self,host, username, password): 
     self.ftp = FTP(host) 
     self.ftp.login(username, password) 
     self.get(self.file_path) 

    def get(self,filename): 
     self.f = open(filename, 'wb') 
     self.ftp.retrbinary('RETR ' + filename, self.handleDownload) 
     self.f.close() 
     self.ftp.close 

a = ftpness() 

ответ

0

ошибка 421 является ошибкой тайм-аута std. поэтому нужно иметь соединение, пока файл не будет загружен.

def handleDownload(self,block): 
     self.f.write(block) 
     if os.path.getsize(self.file_path) >117625: 
       self.ftp.abort() 
     else: 
       self.ftp.sendcmd('NOOP') 
#try to add this line just to keep the connection alive. 

надеюсь, что это вам поможет. :)

+0

Я попробовал ваш код, он висит :) – unice

+0

«FTP.abort() - > Отмените перенос файла, который выполняется. Использование этого не всегда работает, но стоит попробовать. " это то, что мы можем найти в документации ... не могли бы вы сообщить мне, если ошибка тайм-аута ушла? – blackwind

+0

Он по-прежнему вызывает ошибку тайм-аута. Я читал о ftp.abort(), поэтому я хочу знать, есть ли другой способ остановить загрузку без этой ошибки таймаута. – unice

0

Вот как это сделать с помощью сторожевого таймера. Это предполагает создание отдельного потока, который в зависимости от дизайна вашего приложения может быть неприемлем.

Чтобы убить загрузку с помощью пользовательского события, это та же идея. Если графический интерфейс работает в отдельном потоке, то этот поток может просто попасть внутрь экземпляра FTP и закрыть его сокет напрямую.

from threading import Timer 

class ftpness: 
    ... 

    def connect(self,host, username, password): 
     self.ftp = FTP(host) 
     self.ftp.login(username, password) 
     watchdog = Timer(self.timeout, self.ftp.sock.close) 
     watchdog.start() 
     self.get(self.file_path) 
     watchdog.cancel() # if file transfer succeeds cancel timer 

Таким образом, если передача файлов работает дольше, чем ваше заранее установленное время ожидания, поток таймера будет закрыть сокет под передачей, заставляя get вызов сгенерирует исключение. Только когда передача завершается успешно, сторожевой таймер отменяется.

И хотя это не имеет никакого отношения к вашему вопросу, обычно вызов connect не должен передавать данные полезной нагрузки.

0

Это слишком долгое время простоя вашего сеанса. Вы можете подать после президента в экземпляр ftplib. В противном случае. Измените конфигурацию программного обеспечения ftp.

Например, вы используете VSFTPD, вы можете добавить следующую конфигурацию vsftpd.conf:

idle_session_timeout=60000 # The default is 600 seconds

Смежные вопросы