【问题标题】:python ftplib hangs on upload (STOR) --- and not network latencypython ftplib 在上传 (STOR) 时挂起 --- 而不是网络延迟
【发布时间】:2016-05-16 17:10:46
【问题描述】:

我有一个非常简单的实用程序脚本,在 python 2.7 上使用 ftplib 将 Web 文件上传到我的远程主机。然而,storlines 挂了,只是在那里坐了几分钟。没有礼貌地抛出任何异常。

  • 我已验证连接可以从 REPL 工作。 storlines 从 REPL 和命令行脚本都挂起。

  • 我的测试文件是 22 字节(不是 KB,字节),所以事情似乎不太可能只是超时。此外,在 REPL 中,通过 cntrl-c 终止挂起的上传后,我可以从 ftp.dir() 获得输出,所以我知道我不会在某些时候失去连接。

  • ftp.dir() 的上述输出比我的测试文件大得多,并且在几秒钟内到达,所以我知道问题不在于网络延迟。

  • 基于this prior SO 我已经尝试在上传函数定义之前添加ftp.set_pasv(False),但这确实没有用。

还有其他人对这里可能出现的问题有任何想法吗?代码如下:

import sys
from ftplib import FTP
ftp = FTP([MYSERVER], [MYUSER], [MYPASSWORD])
full = sys.argv[1]
path = 'public_html/' + full[:full.rfind('/') + 1]
filename = full[full.rfind('/') + 1:]
ftp.cwd(path)

def upload(method, mode, filename):
    with open(filename, mode) as fileobject:
        method('STOR' +filename, fileobject)

if filename.endswith(('.htm','.html','.py','.cgi','.js','.css','.txt','.md', '.svg')):
    upload(ftp.storlines, 'r', filename)
else:
    upload(ftp.storbinary, 'rb', filename)
ftp.quit()
print 'Done!'

说真的,这是我要上传的完整文件,文件名为 test.md:

this is a test. 
#test

【问题讨论】:

  • 您是否尝试过使用其他 FTP 客户端? FTP 是一种协议,它对 NAT 或防火墙的行为非常糟糕,而且 PASV 并不总是有帮助。因此,这很可能与 python 无关,而是与客户端和服务器之间的一般 FTP 相关的连接问题。仅连接到端口 21 是不够的,因为 FTP 使用动态端口来传输文件。
  • 嗯。部分问题是我对网络知之甚少。 :-( 否则我只尝试过使用 GUI 应用程序(在 OSX 上获取工作正常),而且我的家庭 dsl 连接不太好,所以我的一端不像有某种公司防火墙可以通过。但是是的,谁知道服务器端发生了什么,或者,就此而言,我的 isp 创造了这方面的噩梦。呃。
  • DSL 连接上的典型噩梦可能涉及DS-Lite,您无法获得公共 IPv4 地址。在这种情况下,ISP 需要使用一些辅助应用程序来处理 FTP 流量,这通常只是增加了一些混乱行为。如果可能的话,远离 FTP 来传输数据,除了简单的网络设置之外,它只是一场噩梦。
  • 谢谢。对于这里发生的事情,这似乎是一个非常合理的解释。呃。

标签: python ftp


【解决方案1】:

所以这很难看,但我最终想出了一个 hack-tastic 解决方案,它只是让由真正了解网络的人编写的现有 ftp 应用程序完成工作:

import sys
import os
full = sys.argv[1]
path = 'public_html/' + full[:full.rfind('/') + 1]
filename = full[full.rfind('/') + 1:]

def picktype(filename):
    if filename.endswith(('.htm','.html','.py','.cgi','.js','.css','.txt','.md', '.svg')):
        return 'ascii'
    return 'binary'

ftpstring = """
open [SERVER]
user [USER] [PASSWORD]
cd {0}
{1}
put {2}
bye
""".format(path, picktype(filename), filename)

print ftpstring

with open("tempfile.txt", 'w') as tempfile:
    tempfile.write(ftpstring)

os.system('ftp -n < tempfile.txt')

print 'Done!'

我知道这些天你应该使用subprocess 模块来处理这种垃圾,但我一生都无法弄清楚如何使重定向工作。

【讨论】:

    【解决方案2】:

    我遇到了和你一样的问题。 当我在 ms cmd 控制台中运行它时,我的 python ftp 脚本挂起,没有任何输出。我什至用多线程、多进程重写了我的脚本,但它不起作用。 但我发现我的脚本在 linux 中正常运行,或者在 windows 上的 pycharm ide 中运行。

    所以我认为这可能是 ms cmd 环境的一些问题。然后我发现了这些问题python program stops in command line, command freezing

    我尝试禁用 cmd 的“QuickEdit Mode”选项。它有效!

    【讨论】:

      猜你喜欢
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 2017-10-03
      • 1970-01-01
      相关资源
      最近更新 更多