一、什么是因特网客户端
这里,我们将详细了解三个因特网协议——FTP, NNTP 和 POP3,并写出它们的客户端程序
二、文件传输
2.1 文件传输因特网协议
1、因特网中最流行的事情就是文件的交换,文件交换无处不在
2、有很多协议可以供因特网上传输文件使用
3、最流行的有文件传输协议(FTP),Unix-to-Unix 复制协议(UUCP),以及网页的超文本传输协议(HTTP)
4、另外, 还有 (Unix 下的) 远程文件复制指令 rcp (以及更安全, 更灵活的 scp 和 rsync)
5、HTTP 主要用于网页文件的下载和访问 Web服务上。它一般不要求用户输入登录的用户名密码就可以访问服务器上的文件和服务
6、HTTP 文件传输请求主要是用于获取网页(文件下载)
7、scp 和 rsync 要求用户登录到服务器, 否则不能上传或下载文件
8、至于 FTP, 跟 scp/rsync一样,可以上传或下载文件,还采用了 Unix 的多用户的概念,用户一定要输入有效的用户名和密码才能使用。不过,FTP 也允许匿名登录
2.2 文件传输协议(FTP)
1、FTP 要求输入用户名和密码才能访问远程的 FTP 服务器, 但它也允许没有帐号的用户以匿名用户登录。不过,管理员要先设置 FTP 服务器允许匿名用户登录
2、在底层上,FTP 只使用 TCP
3、FTP的客户端和服务器都使用两个套接字来通讯:一个是控制和命令端口(21 号端口),另一个是数据端口(有时是 20 号端口)
4、客户端和服务器使用指令和控制端口发送 FTP 协议,而数据通过数据端口传输。
其工作流程如下:
1.客户端连接远程的 FTP 服务器
2. 客户端输入用户名和密码(或“anonymous”和 e-mail 地址)
3. 客户端做各种文件传输和信息查询操作
4. 客户端登出远程 FTP 服务器,结束通讯
FTP 有两种模式:主动和被动
1、只有在主动模式服务器才使用数据端口
2、在服务器把 20 号端口设置为数据端口后,它“主动”连接客户端的数据端口
3、而被动模式中,服务器只是告诉客户端它的随机端口的号码,客户端必须主动建立数据连接。在这种模式下,你会看到,
FTP 服务器在建立数据连接时是“被动”的
2.3 Python 和 FTP
1、在使用 Python 的 FTP 支持时,你所需要做的就是导入 ftplib 模块,并实例化一个 ftplib.FTP类对象。 所有的 FTP 操作 (如登录, 传输文件和登出等)都要使用这个对象来完成 ,例如:
from ftplib import FTP
f = FTP('ftp.python.org')
f.login('anonymous', 'guess@who.org')
:
f.quit()
2.4 ftplib.FTP 类方法
FTP 对象的最常用方法
login(user='anonymous',passwd='', acct='') :登录到 FTP 服务器,所有的参数都是可选的
pwd() :得到当前工作目录
cwd(path) :把当前工作目录设置为 path
dir([path[,...[,cb]]) :显示 path 目录里的内容,可选的参数 cb 是一个回调函数,它会被传给 retrlines()方法
nlst([path[,...]) :与 dir()类似,但返回一个文件名的列表,而不是显示这些文件名
retrlines(cmd [, cb]) :给定 FTP 命令(如“RETR filename”),用于下载文本文件。可选的回调函数 cb 用于处理文件的每一行
retrbinary(cmd, cb[,bs=8192[, ra]]) :与 retrlines()类似,只是这个指令处理二进制文件。
回调函数 cb 用于处理每一块(块大小默认为 8K)下载的数据。
storlines(cmd, f): 给定 FTP 命令(如“STOR filename”),以上传文本文件。要给定一个文件对象 f
storbinary(cmd, f[,bs=8192]) :与 storlines()类似,只是这个指令处理二进制文件。
要给定一个文件对象 f,上传块大小 bs 默认为 8Kbs=8192])
rename(old, new) :把远程文件 old 改名为 new
delete(path) :删除位于 path 的远程文件
mkd(directory) :创建远程目录
rmd(directory): 删除远程目录
quit() :关闭连接并退出
二、高级功能模块
1、使用ftplib下载文件
启动状态下:
service vsftpd start >>> import ftplib >>> ftplib.__file__ >>> ftp = ftplib.FTP('localhost') >>> ftp.getwelcome() '220 (vsFTPd 2.2.2)' >>> ftp.login('ftp') '230 Login successful. >>> ftp.pwd() '/' >>> ftp.dir() drwxr-xr-x 2 0 0 4096 Mar 02 2012 pub
关闭状态下:
service vsftpd stop >>> ftp = ftplib.FTP('localhost') #这时会报socke.error错误。 >>> ftp = ftplib.FTP('localhosts') #这时会报socket.gaierror
版本1:
#!/usr/bin/env python
from ftplib import FTP
import sys
import socket
def getfile():
try:
f = FTP('localhost')
except (socket.gaierror, socket.error), e:
print 'connection error:', e
sys.exit(1)
f.login('ftp', 'aa@aa.com')
f.cwd('pub')
f.dir()
fname = raw_input('download file: ')
f.retrbinary('RETR %s' % fname, open(fname, 'w').write)
f.quit()
def main():
getfile()
if __name__ == '__main__':
main()
版本2:
[root@svr5 py]# cat ftpcl.py
#!/usr/bin/env python
#coding:utf8
import ftplib
import sys
import socket
def getfile():
try:
f = ftplib.FTP('localhost')
except (socket.gaierror, socket.error), e:
print 'Error:', e
sys.exit(1)
f.login('ftp')
print f.getwelcome()
f.cwd('pub')
print 'change dir:',f.pwd()
print 'file list:'
f.dir()
fname = raw_input('download file: ') #pub目录下需要有文件,否则无法下载
f.retrbinary('RETR %s' % fname, open(fname, 'w').write)
f.quit()
def main():
getfile()
if __name__ == '__main__':
main()
执行结果:
[root@svr5 py]#
[root@svr5 py]# ./ftpcl.py
220 (vsFTPd 2.2.2)
change dir: /pub
file list:
-rw-r--r-- 1 0 0 0 Dec 02 14:04 a.txt
download file: a.txt
[root@svr5 py]# ls
a.txt counter.py ftpcl.py info.py mathgame.py passwd
balance.txt finance.py hotel.py initm.py mypack record.txt
2、使用OOP的方式下载FTP文件
版本1:
#!/usr/bin/env python from ftplib import FTP class DownloadFile(object): def __init__(self, ftpst): self.ftpsite = ftpst def getFile(self): f = FTP(self.ftpsite) f.login('ftp', 'aa@aa.com') f.dir() chdir = raw_input('enter dir: ') f.cwd(chdir) f.dir() fname = raw_input('download file: ') f.retrbinary('RETR %s' % fname, open(fname, 'w').write) f.quit() def main(): ftpsite = raw_input('ftp site: ') myftp = DownloadFile(ftpsite) myftp.getFile() if __name__ == '__main__': main()