Возобновить загрузку по FTP после тайм-аута - PullRequest
6 голосов
/ 03 августа 2011

Я загружаю файлы с ненадежного FTP-сервера, который часто отключается во время передачи файлов, и мне было интересно, есть ли способ восстановить соединение и возобновить загрузку.Я использую ftplib Python.Вот код, который я использую:

#! /usr/bin/python

import ftplib
import os
import socket
import sys

#--------------------------------#
# Define parameters for ftp site #
#--------------------------------#
site           = 'a.really.unstable.server'
user           = 'anonymous'
password       = 'someperson@somewhere.edu'
root_ftp_dir   = '/directory1/'
root_local_dir = '/directory2/'

#---------------------------------------------------------------
# Tuple of order numbers to download. Each web request generates 
# an order numbers
#---------------------------------------------------------------
order_num = ('1','2','3','4')

#----------------------------------------------------------------#
# Loop through each order. Connect to server on each loop. There #
# might be a time out for the connection therefore reconnect for #
# every new ordernumber                                          #
#----------------------------------------------------------------#
# First change local directory
os.chdir(root_local_dir)

# Begin loop through 
for order in order_num:

    print 'Begin Proccessing order number %s' %order

    # Connect to FTP site
    try:
        ftp = ftplib.FTP( host=site, timeout=1200 )
    except (socket.error, socket.gaierror), e:
        print 'ERROR: Unable to reach "%s"' %site
        sys.exit()

    # Login
    try:
        ftp.login(user,password)
    except ftplib.error_perm:
        print 'ERROR: Unable to login'
        ftp.quit()
        sys.exit()

    # Change remote directory to location of order
    try:
        ftp.cwd(root_ftp_dir+order)
    except ftplib.error_perm:
        print 'Unable to CD to "%s"' %(root_ftp_dir+order)
        sys.exit()

    # Get a list of files
    try:
        filelist = ftp.nlst()
    except ftplib.error_perm:
        print 'Unable to get file list from "%s"' %order
        sys.exit()

    #---------------------------------#
    # Loop through files and download #
    #---------------------------------#
    for each_file in filelist:

        file_local = open(each_file,'wb')

        try:
            ftp.retrbinary('RETR %s' %each_file, file_local.write)
            file_local.close()
        except ftplib.error_perm:
            print 'ERROR: cannot read file "%s"' %each_file
            os.unlink(each_file)

    ftp.quit()

    print 'Finished Proccessing order number %s' %order

sys.exit()

Ошибка, которую я получаю: socket.error: [Errno 110] Истекло время ожидания соединения

Любая помощь очень ценится.

Ответы [ 2 ]

4 голосов
/ 04 августа 2011

Для возобновления загрузки через FTP с использованием только стандартных средств (см. RFC959 ) требуется использование режима блочной передачи (раздел 3.4.2), который можно установить с помощью команды MODE B.Хотя эта функция технически необходима для соответствия спецификации, я не уверен, что все программное обеспечение сервера FTP реализует ее.

В режиме блочной передачи, в отличие от режима потоковой передачи, сервер отправляет файл вкуски, у каждого из которых есть маркер.Этот маркер может быть повторно отправлен на сервер для перезапуска неудачной передачи (раздел 3.5).

В спецификации сказано:

[...] процедура перезапуска предоставляетсязащитить пользователей от серьезных системных сбоев (включая сбои хоста, FTP-процесса или базовой сети).

Однако, согласно спецификации AFAIK, срок службы маркеров не определяется.В нем говорится только следующее:

Информация маркера имеет значение только для отправителя, но должна состоять из печатных символов на языке по умолчанию или согласованном языке управляющего соединения (ASCII или EBCDIC).Маркер может представлять счетчик битов, счетчик записей или любую другую информацию, с помощью которой система может идентифицировать контрольную точку данных.Получатель данных, если он реализует процедуру перезапуска, затем маркирует соответствующую позицию этого маркера в принимающей системе и возвращает эту информацию пользователю.

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

0 голосов
/ 04 августа 2011

Чтобы сделать это, вам нужно будет сохранить прерванную загрузку, затем выяснить, какие части файла вам не хватает, загрузить эти части и затем соединить их вместе.Я не уверен, как это сделать, но есть менеджер загрузок для Firefox и Chrome, который называется DownThemAll, который делает это.Хотя код написан не на python (я думаю, что это JavaScript), вы можете посмотреть код и посмотреть, как он это делает.

DownThemll - http://www.downthemall.net/

...