带有FTPS的ftplib storbinary挂起/从未完成 [英] ftplib storbinary with FTPS is hanging/never completing

查看:109
本文介绍了带有FTPS的ftplib storbinary挂起/从未完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用FTPS将文件上传到FTP站点,但是当我尝试存储文件时,它在文件完全传输后挂起.

I am trying to upload a file to an FTP site using FTPS, but when I attempt to store the file, it just hangs after the file is fully transferred.

global f_blocksize
global total_size
global size_written
f_blocksize = 1024
total_size = os.path.getsize(file_path)
size_written = 0
file = open(file_path, "rb")
try:
    ftps = FTP_TLS("ftp.example.com")
    ftps.auth()
    ftps.sendcmd("USER username")
    ftps.sendcmd("PASS password")
    ftps.prot_p()
    print(ftps.getwelcome())

    try:
        print("File transfer started...")
        ftps.storbinary("STOR myfile.txt", file, callback=handle, blocksize=f_blocksize)
        print("File transfer complete!")
    except OSError as ex:
        print(ftps.getresp())
except Exception as ex:
    print("FTP transfer failed.")
    print("%s: %s" %(type(ex), str(ex)))

def handle(block):
    global size_written
    global total_size
    global f_blocksize
    size_written = size_written + f_blocksize if size_written + f_blocksize < total_size else total_size
    percent_complete = size_written / total_size * 100
    print("%s percent complete" %str(percent_complete))

我得到以下输出:

220 Microsoft FTP Service
File transfer started...
3.5648389904264577 percent complete
7.129677980852915 percent complete
10.694516971279374 percent complete
14.25935596170583 percent complete
17.824194952132288 percent complete
21.389033942558747 percent complete
24.953872932985206 percent complete
28.51871192341166 percent complete
32.083550913838124 percent complete
35.648389904264576 percent complete
39.213228894691035 percent complete
42.778067885117494 percent complete
46.342906875543946 percent complete
49.90774586597041 percent complete
53.472584856396864 percent complete
57.03742384682332 percent complete
60.60226283724979 percent complete
64.16710182767625 percent complete
67.7319408181027 percent complete
71.29677980852915 percent complete
74.8616187989556 percent complete
78.42645778938207 percent complete
81.99129677980854 percent complete
85.55613577023499 percent complete
89.12097476066144 percent complete
92.68581375108789 percent complete
96.25065274151436 percent complete
99.81549173194082 percent complete
100.0 percent complete

此后,直到连接超时为止,没有进一步的进展...

After which there is no further progress until the connection times out...

FTP transfer failed.
<class 'ftplib.error_temp'>: 425 Data channel timed out due to not meeting the minimum bandwidth requirement.

程序运行时,如果我手动连接并查看,在FTP站点中可以看到一个空的 myfile.txt ,但是当我取消它或连接超时时,该空文件消失了.

While the program is running I can see an empty myfile.txt in the FTP site if I connect and look manually, but when I either cancel it or the connection times out, this empty file disappears.

在文件完全传输后,我是否需要丢失某些内容来关闭文件?

Is there something I'm missing that I need to invoke to close the file after it has been completely transferred?

推荐答案

这似乎与Python的 SSLSocket 类有关,该类正在运行 unwrap .由于它从不从服务器接收此数据,因此它无法从套接字中解开SSL,因此超时.

This appears to be an issue with Python's SSLSocket class, which is waiting for data from the server when running unwrap. Since it never receives this data from the server, it is unable to unwrap SSL from the socket and therefore times out.

我特别通过欢迎消息将此服务器标识为某些Microsoft FTP服务器,它非常适合

This server in particular I have identified by the welcome message as some Microsoft FTP server, which fits in well with the issue written about in this blog

修复"(如果可以这样称呼)是通过编辑 ftplib.py 并修改 FTP_TLS.storbinary()方法.

The "fix" (if you can call it that) was to stop the SSLSocket from attempting to unwrap the connection altogether by editing ftplib.py and amending the FTP_TLS.storbinary() method.

def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None):
  self.voidcmd('TYPE I')
  with self.transfercmd(cmd, rest) as conn:
    while 1:
      buf = fp.read(blocksize)
      if not buf: break
      conn.sendall(buf)
      if callback: callback(buf)
    # shutdown ssl layer
    if isinstance(conn, ssl.SSLSocket):
      # HACK: Instead of attempting unwrap the connection, pass here
      pass
  return self.voidresp()

这篇关于带有FTPS的ftplib storbinary挂起/从未完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆