python - ftplib अजगर: एनओओपी कमांड एएससीआईआई बाइनरी में काम करता है



multithreading sockets (1)

मेरे पास एक थ्रेडेड एफ़टीपी स्क्रिप्ट है जबकि डेटा सॉकेट डेटा प्राप्त कर रहा है, एक थ्रेडेड लूप, बड़े स्थानान्तरण के दौरान नियंत्रण कनेक्शन को रखने के लिए, नियंत्रण सॉकेट पर 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) एएससीआईआई स्थानान्तरण के लिए चूक है और मैं वीडियो को स्थानांतरित कर ftp.voidcmd('TYPE I) इसलिए इसे बाइनरी होना चाहिए (इसलिए ftp.voidcmd('TYPE I) द्विआधारी मोड को मजबूर करने के लिए कॉल करें)।

अगर मैं फोन पर ftp.voidcmd('TYPE I) कॉल ftp.voidcmd('TYPE I) तो NOOP कमांड सफलतापूर्वक भेजते हैं और आउटपुट निम्नानुसार है:

*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'

आदि। लेकिन फ़ाइल एएससीआईआई में है और इसके लिए दूषित है। अगर मैं ftp.voidcmd('TYPE I) कॉल करता ftp.voidcmd('TYPE I) तो ftp.voidcmd('TYPE I) कमांड केवल एक बार भेजता है, और जब तक स्थानांतरण पूरा नहीं हो जाता तब तक नियंत्रण सॉकेट का जवाब नहीं होता। यदि फ़ाइल बड़ी है, तो नियंत्रण सॉकेट बार जैसे कि NOOPs कभी नहीं भेजा गया था ...

बहुत अजीब है, लेकिन मुझे यकीन है कि इसकी सरलता ऐसा लगता है कि transfercmd() नियंत्रण और डेटा सॉकेट को विभाजित नहीं कर रहा है जैसा कि यह माना जाता है ... और इसलिए एफटीपी var डेटा स्ट्रीम से अलग नहीं है ... या कुछ और अजीब।

किसी भी सलाह के लिए अग्रिम धन्यवाद जो आप कर सकते हैं


tcpdump पुष्टि करता है कि सर्वर केवल 226 Transfer complete. भेजता है 226 Transfer complete. संपूर्ण फाइल सर्वर द्वारा भेजी जाने के बाद

मुझे संदेह है कि एफ़टीपी विनिर्देशन का हिस्सा है

वास्तव में, retrbinary कोड को ftplib.py में ftplib.py :

    self.voidcmd('TYPE I')
    conn = self.transfercmd(cmd, rest)
    while 1:
        data = conn.recv(blocksize)
        if not data:
            break
        callback(data)
    conn.close()
    return self.voidresp()

ट्रैनफर पूरा हो जाने के बाद ही आखिरी पंक्ति ट्रांफ़र परिणाम (जैसा कि सर्वर को ज्ञात है) प्राप्त करने की अपेक्षा करता है

वास्तव में ऐसा लगता है कि आपका कोड voidresp() बिट लापता है

मैं एफ़टीपी से बहुत परिचित नहीं हूँ, मैंने जो पृष्ठभूमि डाउनलोडर्स जैसे lftp वास्तव में प्रत्येक समानांतर डाउनलोड के लिए नए नियंत्रण कनेक्शन खोलते देखा है।

आपकी फ़ाइल वास्तव में बड़ी है अगर आपके पास एक वैध चिंता है

एफ़टीपी के लिए कई एक्सटेंशन हैं, ऐसा कुछ हो सकता है जो आप चाहते हैं

वैकल्पिक रूप से आप एक लूप को यह पसंद कर सकते हैं:

pos = 0
while not full file:
    command REST
    download for a while in separate thread
    command ABRT
    wait for separate thread to abort
    pos += length of downloaded chunk




noop