0 前言:
ftp客户端相信大家都用过,那么我们为什么还要用Python写ftp客户端呢?
我想有两个原因:
一是写出更好的ftp客户端应用程序,方便大家使用;
二是定制一些特殊服务,例如每天定时下载/上传某文件;
我还没能力也没时间写出ftp客户端应用程序,前期先分析一下python写ftp客户端的核心部分,即实现上传和下载的关键部分。
首先看一下ftp服务器/客户端架构:
1 FTP服务器/客户端
ftp架构
上图展示了ftp的工作流程:
1.客户端连接远程主机上的FTP 服务器。
2.客户端输入用户名和密码(或“anonymous”和电子邮件地址)。
3.客户端进行各种文件传输和信息查询操作。
4.客户端从远程FTP 服务器退出,结束传输。
下面是一段Python伪代码。
from ftplib import FTP f = FTP('some.ftp.server') f.login('anonymous', 'your@email.address') : f. quit()
当然,这只是一般情况下的流程。有时,由于网络两边计算机的崩溃或网络的问题,会导致整个传输在完成之前就中断。
如果客户端超过15 分钟(900 秒)还没有响应,FTP 连接就会超时并中断。
在底层,FTP 只使用TCP,而不使用UDP。
另外,可以将FTP 看作客户端/服务器编程中的特殊情况。因为这里的客户端和服务器都使用两个套接字来通信:
一个是控制和命令端口(21 号端口),另一个是数据端口(有时是20 号端口),如上图 所示。
FTP 有两种模式:主动和被动。只有在主动模式下服务器才使用数据端口。
在服务器把20 号端口设置为数据端口后,它“主动”连接客户端的数据端口。而在被动模式下,服务器只是告诉客户端随机的数据端口号,客户端必须主动建立数据连接。
2 客户端FTP 程序示例
#!/usr/bin/env python# coding=utf-8import ftplib import os import socket import pdb HOST = 'ftp.debian.org'DIRN = 'debian/tools'FILE = 'loadlin.exe'def main(): try: f = ftplib.FTP(HOST) except (socket.error, socket.gaierror) as e: print 'ERROR: cannot reach "%s"' % HOST return print '*** Connected to host "%s"' % HOST try: f.login() except ftplib.error_perm: print 'ERROR: cannot login anonymously' f.quit() return print '*** Logged in as "anonymous"' try: f.cwd(DIRN) except ftplib.error_perm: print 'ERROR: cannot CD to "%s"' % DIRN f.quit() return print '*** changed to "%s" folder' % DIRN try: f.retrbinary('RETR %s' % FILE, open(FILE,'wb').write) except ftplib.error_perm: print 'ERROR: cannot read file "%s"' % FILE os.unlink(FILE) else: print '*** Download "%s" to CWD' %FILE f.quit()if __name__ == '__main__': main()
运行结果:
ftp客户端运行结果:可以看出loadlin.exe文件被更新了。
3 疑问
上面编写的客户端代码对ftp.debian.org
站点可以正常连接,为什么有的ftp服务器明明可以ping通却无法连接?
ping ftp.python.org
然而,却无法连接到服务器:
无法连接ftp.python.org
请高人指点!!谢谢!!
作者:rebirth_2017
链接:https://www.jianshu.com/p/bb8207a1ff75
共同学习,写下你的评论
评论加载中...
作者其他优质文章