来源:Rebirth_2017 发布时间:2018-11-03 15:48:45 阅读量:1518
0 前言:
ftp客户端相信大家都用过,那么我们为什么还要用Python写ftp客户端呢?
我想有两个原因:
一是写出更好的ftp客户端应用程序,方便大家使用;
二是定制一些特殊服务,例如每天定时下载/上传某文件;
我还没能力也没时间写出ftp客户端应用程序,前期先分析一下python写ftp客户端的核心部分,即实现上传和下载的关键部分。
首先看一下ftp服务器/客户端架构:
1 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()
1
2
3
4
5
当然,这只是一般情况下的流程。有时,由于网络两边计算机的崩溃或网络的问题,会导致整个传输在完成之前就中断。
如果客户端超过15 分钟(900 秒)还没有响应,FTP 连接就会超时并中断。
在底层,FTP 只使用TCP,而不使用UDP。
另外,可以将FTP 看作客户端/服务器编程中的特殊情况。因为这里的客户端和服务器都使用两个套接字来通信:
一个是控制和命令端口(21 号端口),另一个是数据端口(有时是20 号端口),如上图 所示。
FTP 有两种模式:主动和被动。只有在主动模式下服务器才使用数据端口。
在服务器把20 号端口设置为数据端口后,它“主动”连接客户端的数据端口。而在被动模式下,服务器只是告诉客户端随机的数据端口号,客户端必须主动建立数据连接。
2 客户端FTP 程序示例
#!/usr/bin/env python
# coding=utf-8
import 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()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
运行结果:
3 疑问
上面编写的客户端代码对ftp.debian.org站点可以正常连接,为什么有的ftp服务器明明可以ping通却无法连接?
然而,却无法连接到服务器:
---------------------
作者:Rebirth_2017
来源:CSDN
原文:https://blog.csdn.net/zhou8201/article/details/71526455
版权声明:本文为博主原创文章,转载请附上博文链接!