因特网客户端简介
. 这里将因特网理解为用来传输数据的地方,数据在服务提供者和服务使用者之间传输,在某种情况下被称为“生产者-消费者”,服务器就是生产者,提供服务,而客户端使用服务。
文件传输
文件传输因特网协议
. 因特网中最常见的就是传输文件,许多协议可以用于在因特网上传输文件。最流行包括文件传输协议(FTP)、UNIX到UNIX复制协议(UUCP)、用于web的超文本传输协议(HTTP)。另外还有(UNIX下的)远程文件复制命令如此rcp(以及更安全、更灵活的scp和rsync)。
HTTP主要用于基于web的文件下载以及访问web服务,一般客户端无须登录就可以访问服务器上的文件和服务。大部分HTTP 文件传输请求都用于获取网页(即将网页文件下载到本地)。
而 scp 和 rsync 需要用户登录到服务器主机。在传输文件之前必须验证客户端的身份,否则不能上传或下载文件。FTP 与 scp/rsync 相同,它也可以上传或下载文件,并采用了 UNIX 的多用户概念,用户需要输入有效的用户名和密码。但 FTP 也允许匿名登录。
文件传输协议
. FTP主要用于匿名下载公共文件,也可用于两台计算机之间传输文件。早在web流行之前,FTP就是在因特网上进行文件传输以及下载软件和源代码的主要手段之一。
前面提过,FTP要求输入用户名和密码才能访问FTP服务器,但也允许没有账号的用户匿名登录,不过管理员要先设置FTP服务器允许匿名用户登录,但与登录用户相比,匿名用户只能使用有限的几个FTP命令。
FTP协议的工作流程基本如下:
1.客户端连接远程主机上的FTP服务器;
2.客户端输入账号和密码;
3.客户端进行文件传输或各种信息查询;
4.客户端从远程FTP服务器退出,结束传输。
有时由于网络两边计算机的崩溃或是网络的问题,会导致整个传输在完成之前就被中断。如果客户端超过15分钟还没有响应,FTP连接就会超时并中断。
在底层,FTP使用的是TCP。可以将FTP看做客户端/服务器编程中的特殊情况,因为这里的服务器和客户端都使用两个套接字来通信:一个是控制和命令端口(21端口),一个是数据端口(有时是20端口)。之所以说是“有时”是因为FTP有两种模式:主动和被动。只有在主动模式下服务器才使用数据端口。在服务器将20号端口设置为数据端口后,它“主动”连接客户端的数据端口;而在被动模式下,服务器只是告诉客户端一个随机的数据端口号,客户端必须主动建立数据连接。
Python与FTP
. Python编写FTP客户端程序的流程如下:
1.连接到服务器;
2.登录;
3.发出服务请求(希望得到响应);
4.退出。
在使用Python的FTP支持时,所需要做的就是导入ftplib模块,并实例化一个ftplib.FTP类对象,通过该对象来完成FTP的所有操作。
ftplib.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 用于处理每一块(块大小默认为 8KB)下载的数据 |
storlines(cmd, f) | 给定 FTP 命令(如“STOR filename”),用来上传文本文件。要给定一个文件对象 f |
storbinary(cmd, f[,bs=8192]) | 与 storlines()类似,只是这个指令处理二进制文件。要给定一个文件对象 f,上传块大小 bs 默认为 8KB |
rename(old, new) | 把远程文件 old 重命名为 new |
delete(path) | 删除位于 path 的远程文件 |
mkd(directory) | 创建远程目录 |
rmd(directory) | 删除远程目录 |
quit() | 关闭连接并退出 |
客户端FTP程序示例
. 以下代码用来从ftp服务器下载文件:(PS:书上的FTP服务器地址我反正是连接不上,本想照着网上的步骤自己搭建FTP服务器,结果不知道是系统版本还是什么问题无法做到,所以用了别人私人的服务器地址,就不写信息了,只能说正常情况下代码是可以正常工作的。)
import ftplib
import os
import socket
Host = 'xxx.xxx.xxx.xxx'
Dirn = 'xxx/xxx/'
File = 'xxx'
def main():
try: #连接到服务器
f = ftplib.FTP(Host)
except (socket.error,socket.gaierror) as e:
print('无法连接到 "%s"' % Host)
return
print('成功连接到 "%s"' % Host)
try: #登录
f.login('xxx','xxx')
except ftplib.error_perm:
print('登录失败')
f.quit()
return
print('登录成功')
#print(f.pwd())
try: #更换工作目录
f.cwd(Dirn)
except ftplib.error_perm:
print('无法进入"%s"' % Dirn)
f.quit()
return
print('进入"%s"成功' % Dirn)
try: #下载文件
f.retrbinary('RETR %s' % File,open(File,'wb').write)
except ftplib.error_perm:
print('读取文件失败')
else:
print('文件下载成功')
f.quit()
if __name__ == '__main__':
main()