4

スレッド化された FTP スクリプトがあります。データ ソケットがデータを受信して​​いる間、スレッド ループは制御ソケットに NOOP コマンドを送信して、大規模な転送中に制御接続を維持します。

FTP.retrbinary()制御接続を維持したい場合は、データソケットと制御ソケットを分離する必要があるため、コマンドを使用できretrbinaryません。

以下のコード:

def downloadFile(filename, folder):
    myhost = 'HOST'
    myuser = 'USER'
    passw = 'PASS'
    #login
    ftp = FTP(myhost,myuser,passw)

    ftp.set_debuglevel(2)
    ftp.voidcmd('TYPE I')
    sock = ftp.transfercmd('RETR ' + filename)
    def background():
        f = open(folder + filename, 'wb')
        while True:
            block = sock.recv(1024*1024)
            if not block:
                break
            f.write(block)
        sock.close()
    t = threading.Thread(target=background)
    t.start()
    while t.is_alive():
        t.join(120)
        ftp.voidcmd('NOOP')
    ftp.quit();


私の問題FTP.transfercmd("RETR " + filename)デフォルトはASCII転送で、ビデオを転送しているため、バイナリでなければなりません(したがって、ftp.voidcmd('TYPE I)バイナリモードを強制するための呼び出しです)。

NOOPftp.voidcmd('TYPE I)コマンドを呼び出さないと、正常に送信され、出力は次のようになります。

*cmd* 'NOOP'
*put* 'NOOP\r\n'
*get* '200 NOOP: data transfer in progress\n'
*resp* '200 NOOP: data transfer in progress'
*cmd* 'NOOP'
*put* 'NOOP\r\n'
*get* '200 NOOP: data transfer in progress\n'
*resp* '200 NOOP: data transfer in progress'
*cmd* 'NOOP'
*put* 'NOOP\r\n'
*get* '200 NOOP: data transfer in progress\n'
*resp* '200 NOOP: data transfer in progress'

など。ただし、ファイルは ASCII であるため、破損しています。を呼び出すと、 NOOPftp.voidcmd('TYPE I)コマンドは 1 回だけ送信され、制御ソケットは転送が完了するまで応答しません。ファイルが大きい場合、制御ソケットは NOOP が送信されなかったかのようにタイムアウトします...

非常に奇妙ですが、私はそれが単純だと確信しています。想定どおりに制御ソケットとデータソケットを分割していないようtransfercmd()です...したがって、ftp varはデータストリームから分離されていません...または何か。変。

あなたが提供できるアドバイスを事前に感謝します。

4

1 に答える 1