现在的位置: 首页 > 综合 > 正文

ftp pasv IP变化情况下的处理

2014年01月03日 ⁄ 综合 ⁄ 共 1353字 ⁄ 字号 评论关闭

嗯,这个星期就不写英文了,也不用粤语了,本来星期六只是想回来公司轻轻地写篇BLOG,然后5点左右去游水,怎料一回来,没错,就是给你分配工作,开心吧。不是说这工作不好玩,而是,就像同事对七11的饭一样,食得多就会腻。下周周末开始我再也不回来陪老板呵呵了。而且今日是入职六个月纪念日XD

OK,今个星期解决最有意义的问题,做了一个对python FTP客户端的patch。

情况是这样的,... 省略十万字 ...,于是,我们就在amazon那个IP分配机制下遇到pasv(passive模式)动态改变我指定的IP的情况,简单Google咗下,目前没有英文资料,更别说中文资料了,去解决这个问题。

这个问题是,就是我们用ftp命令直连,也会

ftp> passive
Passive mode on.
ftp> list
?Invalid command
ftp> ls
227 Entering Passive Mode (x1,x2,x3,x4,196,8).

直至timeout。

用fileZilla可以解决这个问题,但是我要用python,所以呢,经过一轮挖掘,终于知道原因如上所述。

pasv会返回一个IP地址和端口号,其中端口号分大细超,然后amazon就是默默地给我们返回一个内网IP,当然,我们可以设置服务器端固定pasv返回的IP地址,但是我不要,我要在客户端处理,所以就有了以下的代码。

from ftplib import FTP, parse227, parse229
class FTPP(FTP):
    """FTP patch version"""
    def __init__(self):
        self.fix_host = None
        FTP.__init__(self)

    def set_pasv(self, val, addr=None):
        '''Use passive or active mode for data transfers.
        set_pasv(val, addr=None)
        With val is False, use the normal PORT mode,
        With val is False, use the PASV command.
        addr means to set a fix ip, no using the pasv return ip.
        '''
        self.passiveserver = val
        self.fix_host = addr

    def makepasv(self):
        if self.af == socket.AF_INET:
            host, port = parse227(self.sendcmd('PASV'))
        else:
            host, port = parse229(self.sendcmd('EPSV'), self.sock.getpeername())
        if self.fix_host is not None:
            host = self.fix_host
        return host, port

用法也极其简单,只要在set_pasv的时候加入IP地址,那么他就固定了。

    ftp = FTPP()
    ftp.set_pasv(True, ip)
    ftp.connect(ip, port, 100)
    ftp.login(name, passwd)
    print ftp.getwelcome()
    ftp.cwd('else')
    print ftp.nlst()

正考虑要不要给python提交个源码XD

【上篇】
【下篇】

抱歉!评论已关闭.