17.1 什么是因特网客户端?
三个因特网协议——FTP, NNTP 和POP3
客户端/服务器模型
17.2 文件传输
文件传输因特网协议
因特网中最流行的事情就是文件的交换。文件交换无处不在。
文件传输协议(FTP)
Unix-to-Unix 复制协议(UUCP)
网页的超文本传输 协议(HTTP)
Unix 下的远程文件复制指令rcp,以及更安全,更灵活的scp 和rsync
HTTP 主要用于网页文件的下载和访问Web 服务上。
HTTP一般不要求用户输入登录的用户名密码就可以访问服务器上的文件和服务。
HTTP 文件传输请求主要是用于获取网页(文件下载)。
scp 和rsync 要求用户登录到服务器,否则不能上传或下载文件。
FTP,跟scp/rsync 一样,可以上传或下载文件,还采用了Unix 的多用户的概念,用户一定要输入有效的用户名和密码才能使用。不过,FTP 也允许匿名登录。
文件传输协议(FTP)
文件传输协议由已故的Jon Postel 和Joyce Reynolds 开发,记录在RFC(Request for Comment)959 号文档中,于1985 年10 月发布。
文件传输协议主要用于匿名下载公共文件。也可以用于在两台 电脑之间传输文件,尤其是在使用Unix 系统做为文件存储系统,使用其它机器来工作的情况。
FTP 要求输入用户名和密码才能访问远程的FTP 服务器,但它也允许没有帐号的用户以匿名用户 登录。
匿名用户通过FTP 协议可以使用的命令与一般的用户相比来说,限制更多。
在底层上,FTP 只使用TCP——它不使用UDP。
FTP 客户端和服务器都使用两个套接字来通讯:一个是控制和命令端口(21 号端口),另一个是数据端口(有时是20 号端口)。
图17-1 因特网上的FTP 客户端和服务器。客户端和服务器使用指令和控制端口发送FTP 协议, 而数据通过数据端口传输。
FTP 有两种模式:主动和被动。
只有在主动模式服务器才使用数据端口。 在服务器把20 号端口设置为数据端口后,它“主动”连接客户端的数据端口。
而被动模式中,服务器只是告诉客户端它的随机端口的号码,客户端必须主动建立数据连接。在这种模式下,你会看到, FTP 服务器在建立数据连接时是“被动”的。
Python 和FTP
在使用Python 的FTP 支持时,你所需要做的就是导入ftplib 模块,并实例化一个ftplib.FTP 类对象。
所有的FTP 操作(如登录,传输文件和登出等)都要使用这个对象来完成。
from ftplib import FTP
f = FTP(‘ftp.python.org‘)
f.login(‘anonymous‘, ‘guess@who.org‘)
:
f.quit()
ftplib.FTP 类方法
交互式FTP 示例
客户端FTP 程序举例
1 #!/usr/bin/env python
2
3 import ftplib
4 import os
5 import socket
6
7 HOST = ‘ftp.mozilla.org‘
8 DIRN = ‘pub/mozilla.org/webtools‘
9 FILE = ‘bugzilla-LATEST.tar.gz‘
10
11 def main():
12 try:
13 f = ftplib.FTP(HOST)
14 except (socket.error, socket.gaierror), e:
15 print ‘ERROR: cannot reach "%s"‘ % HOST
16 return
17 print ‘*** Connected to host "%s"‘ % HOST
18
19 try:
20 f.login()
21 except ftplib.error_perm:
22 print ‘ERROR: Cannnot login anonymously‘
23 f.quit()
24 return
25 print ‘*** Logged in as "anonymous"‘
26
27 try:
28 f.cwd(DIRN)
29 except ftplib.error_perm:
30 print ‘ERROR: cannot CD to "%s"‘ % DIRN
31 f.quit()
32 return
33 print ‘*** Changed to "%s" folder‘ % DIRN
34
35 try:
36 f.retrbinary(‘RETR %s‘ % FILE,37 open(FILE, ‘wb‘).write)
38 except ftplib.error_perm:
39 print ‘ERROR: cannot read file "%s"‘ % FILE
40 os.unlink(FILE)
41 else:
42 print ‘*** Downloaded "%s" to CWD‘ % FILE
43 f.quit()
44 return
45
46 if __name__ == ‘__main__‘:
47 main()
FTP 的其它方面
Python 同时支持主动和被动模式。注意,在Python2.0 及以前版本中,被动模式支持默认是关 闭的,在Python2.1 及以后版本中,默认是打开的。
17.3 网络新闻
Usenet 与新闻组
Usenet 新闻系统是一个全球存档的“电子公告板”。
Usenet 新闻系统是一个全球存档的“电子公告板”。各种主题的新闻组一应俱全,从诗歌到政治,
从自然语言学到计算机语言,软件到硬件,种植到烹饪,招工,应聘,音乐,魔术,分手,求爱等。
新闻组可以是面向全球泛泛而谈,也可以是只面向某个地理区域。
整个系统是一个由大量计算机组成的一个庞大的全球网络,计算机之间共享Usenet 上的帖子.如
果某一个用户发了一个帖子到本地的Usenet 计算机上,这个帖子会被传播到其它相连的计算机上,
并再由这些计算机传到与它们相连的计算机上,直到这个帖子传播到了全世界,每个人都收到这个帖
子为止.
每个系统都有一个它已经“订阅”的新闻组的列表,它只接收它感兴趣的新闻组里的帖子——
而不是服务器上所有新闻组的帖子。Usenet 新闻组服务内容取决于服务提供者,很多都是可供公众
访问的,也有一些只允许特定的用户使用,例如付费用户,特定大学的学生等。如果Usenet 系统
管理员设置了的话,有可能会要求输入用户名和密码。管理员也可以设置是否只允许上传或只允许
下载。
网络新闻传输协议(NNTP)
供用户在新闻组中下载或发表帖子的方法叫网络新闻传输协议(NNTP)。它由Brain Kantor(加
利福尼亚大学圣地亚哥分校)和Phil Lapsley(加利福尼亚大学伯克利分校)创建并记录在RFC 977
中,于1986 年2 月公布。其后的更新记录在RFC 2980,于2000 年10 月公布。
FTP 需 要不同的端口来做登录,数据传输和控制,而NNTP 只使用一个标准端口119 来做通讯。
图17-2 因特网上的NNTP 客户端和服务器。客户端主要阅读新闻,有时也发帖子。文章会在服 务器之间做同步。
Python 和NNTP
用FTP 一样,我们所要做的就是导入nntplib那个Python 模块,然后要实例化这个类nntplib.NNTP并调用相应的方法。
一般来说,在你登录完成后,你要调用group()方法来选择一个感兴趣的新闻组。
group()方法返回服务器的返回信息,文章的数量,第一个和最后一个文章的ID,以及组的名字。
from nntplib import NNTP
n = NNTP(‘your.nntp.server‘)
r,c,f,l,g = n.group(‘comp.lang.python‘)
...
n.quit()
nntplib.NNTP 类方法
17.4 电子邮件
消息由头域(合起来叫消息头)以及后面可选的消息体组成。
RFC 规定,邮件体是可选的,只有邮件头是必要的。
E-mail 系统组件和协议
消息传输代理 (MTA)
MX(邮件交换Mail eXchange)
发送E-mail
要能发送e-mail,你的邮件客户端一定要连接到一个MTA,它们靠某种协议进行通讯。MTA 之
间通讯所使用的协议叫消息传输系统(MTS)。只有两个MTA 都使用这个协议时,才能进行通讯。在
本节开始时就说过,由于以前存在很多不同的计算机系统,每个系统都使用不同的网络软件,这种
通讯很危险,具有不可预知性。更复杂的是,有的电脑使用互连的网络,而有的电脑使用调制解调
器拨号,消息的发送时间也是不可预知的。事实上,笔者曾经有一封邮件在发送9 个月后才收到!
互连网的速度怎么会这么慢?出于对这些复杂度的考虑,现代e-mail 的基础之一,简单邮件传输协
议(SMTP)于1982 年出现了。
SMTP
SMTP 由已故的Jonathan Postel(加利福尼亚大学信息学院)创建,记录在RFC 821 中,于 1982 年8 月公布。
SMTP 是在因特网上MTA 之间用于消息交换的最常用的MTS。它被MTA 用来把e-mail 从一台主机
传送到另一台主机。在你发e-mail 的时候,你必须要连接到一个外部的SMTP 服务器,这时,你的
邮件程序是一个SMTP 客户端。你的SMTP 服务器也因此成为了你的消息的第一个跳板。
Python 和SMTP
是的,也存在一个smtplib 模块和一个smtplib.SMTP 类要实例化。
跟NNTP 一样,SMTP 通讯时,只要一个端口25。
像NNTP 一样,登录是可选的,只有在服务器打开了SMTP 认证(SMTP-AUTH)时才要登录。
from smtplib import SMTP
n = SMTP(‘smtp.yourdomain.com‘)
...
n.quit()
smtplib.SMTP 类方法
对大多数e-mail 发送程序来说,只有两个方法是必须的:sendmail()和 quit()。
sendmail()的所有参数都要遵循RFC 2822,即e-mail 地址必须要有正确的格式,消息体要有正 确的前导头,前导头后面是两个回车和换行(\r\n)对。
注意,实际的消息体不是必要的。根据RFC 2822,“唯一要求的头信息只有发送日期和发送地址”, 即“Date:”和“From:”:(MAIL FROM, RCPT TO, DATA)
接收E-mail
在家用电脑中运行的应用程序叫邮件用户代理(MUA)。
MUA 从服务器上下载邮件,在这个过程中 可能会自动删除它们(也可能不删除,留在服务器上,让用户手动删除)。
MUA 也必须要能发送邮件,在发送邮件的时候,它要能直接与MTA 用SMTP 进行通讯。
POP 和IMAP
用于下载邮件的第一个协议叫邮局协议(POP),记录在RFC 918 中,于1984 年10 月公布。
邮局协议 (POP)的目的是让用户的工作站可以访问邮箱服务器里的邮件。邮件要能从工作站通过简单邮件传输协议(SMTP)发送到邮件服务器”
在POP 之后几年,出现了另一个协议,叫交互式邮件访问协议(IMAP)
当今世界上占有邮件服务器大多数市场的Microsoft Exchange 就使用IMAP 作 为其下载机制。
图17-3 因特网上的E-Mail 发件人和收件人。客户端通过他们的MUA 和相应的MTA 进行通讯, 来下载和发送邮件。E-Mail 从一个MTA“跳”到另一个MTA,直到到达目的地为止。
Python 和POP3
导入poplib,实例化poplib.POP3 类
from poplib import POP3
p = POP3(‘pop.python.is.cool‘)
p.user(...)
p.pass_(...)
...
p.quit()
poplib.POP3 类方法
17.5 相关模块