FTP
1.要求
1. 多用户同时登陆
2. 用户登陆,加密认证
3. 上传/下载文件,保证文件一致性
4. 不同用户家目录不同,且只能访问自己的家目录
5. 对用户进行磁盘配额、不同用户配额可不同
6. 用户登陆server后,可在家目录权限下切换子目录
7. 查看当前目录下文件,新建文件夹
8. 删除文件和空文件夹
9. 充分使用面向对象知识
10. 传输过程中现实进度条
11. 支持断点续传
2.流程图
3.代码准备
字符串操作以及打印 —— 实现上传下载的进度条功能
import sys def processBar(num, total): rate = num / total rate_num = int(rate * 100) if rate_num == 100: r = '\r%s>%d%%\n' % ('=' * rate_num, rate_num,) else: r = '\r%s>%d%%' % ('=' * rate_num, rate_num,) sys.stdout.write(r) sys.stdout.flush
改变字符串颜色
print('\033[1;37;32m%s\033[0m'%'周军豪')
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
|
格式:\ 033 [显示方式;前景色;背景色m 说明: 前景色 背景色 颜色 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 30 40 黑色 31 41 红色 32 42 绿色 33 43 黄色 34 44 蓝色 35 45 紫红色 36 46 青蓝色 37 47 白色 显示方式 意义 - - - - - - - - - - - - - - - - - - - - - - - - - 0 终端默认设置 1 高亮显示 4 使用下划线 5 闪烁 7 反白显示 8 不可见 例子: \ 033 [ 1 ; 31 ; 40m <! - - 1 - 高亮显示 31 - 前景色红色 40 - 背景色黑色 - - > \ 033 [ 0m <! - - 采用终端默认设置,即取消颜色设置 - - > |
socketserver —— 实现ftp server端和client端的交互
import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): conn = self.request conn.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding='utf-8')) Flag = True while Flag: data = conn.recv(1024).decode('utf-8') if data == 'exit': Flag = False elif data == '0': conn.sendall(bytes('通过可能会被录音.balabala一大推',encoding='utf-8')) else: conn.sendall(bytes('请重新输入.',encoding='utf-8')) if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1',8008),MyServer) server.serve_forever()
import socket ip_port = ('127.0.0.1',8008) sk = socket.socket() sk.connect(ip_port) sk.settimeout(5) while True: data = sk.recv(1024).decode('utf-8') print('receive:',data) inp = input('please input:') sk.sendall(bytes(inp,encoding='utf-8')) if inp == 'exit': break sk.close()
struct模块 —— 自定制报头解决文件上传下载过程中的粘包问题
import json,struct #假设通过客户端上传1T:1073741824000的文件a.txt #为避免粘包,必须自定制报头 header={'file_size':1073741824000,'file_name':'/a/b/c/d/e/a.txt','md5':'8f6fbf8347faa4924a76856701edb0f3'} #1T数据,文件路径和md5值 #为了该报头能传送,需要序列化并且转为bytes head_bytes=bytes(json.dumps(header),encoding='utf-8') #序列化并转成bytes,用于传输 #为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节 head_len_bytes=struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度 #客户端开始发送 conn.send(head_len_bytes) #先发报头的长度,4个bytes conn.send(head_bytes) #再发报头的字节格式 conn.sendall(文件内容) #然后发真实内容的字节格式 #服务端开始接收 head_len_bytes=s.recv(4) #先收报头4个bytes,得到报头长度的字节格式 x=struct.unpack('i',head_len_bytes)[0] #提取报头的长度 head_bytes=s.recv(x) #按照报头长度x,收取报头的bytes格式 header=json.loads(json.dumps(header)) #提取报头 #最后根据报头的内容提取真实的数据,比如 real_data_len=s.recv(header['file_size']) s.recv(real_data_len)
hashlib模块 —— 实现文件的一致性校验和用户密文登录
os模块 —— 实现目录的切换及查看文件文件夹等功能
文件操作 —— 完成上传下载文件及断点续传等功能
面向对象编程思想+继承知识 —— 组织简化代码
4.文件目录
5.具体代码
http://pan.baidu.com/s/1dEUjBg9
参考:http://www.cnblogs.com/liujiacai/p/7417953.html
既然选择了远方,便是风雨兼程...