需求:
1. 用户登陆
2. 上传/下载文件
3. 不同用户家目录不同
4. 查看当前目录下文件
5. 充分使用面向对象知识
</br>
6. **测试:**
----------
用户登陆
1,用户登陆
2,用户注册
3. 退出
请输入索引进行选择:1
请输入你的用户名(q返回):a
请输入你的密码:a
登陆成功!
请输入你想执行的命令(q退出)>>help
请用'put'+'空格'+'文件名'的格式上传文件
请用'get'+'空格'+'文件名'的格式下载文件
输入'dir'查看用户家目录文件
----------
7. **备注:**
1.程序运行在bin/startclient.py和startserver.py,请先运行server端,在运行client端
2.模拟的本地目录为db/client/目录,下面有两个测试文件a,b
3.模拟的服务器用户家目录为db/home/$name目录
4.测试账号用户名密码为a,a,测试目录为a,下面有两个测试文件,c,d
5.当client段或者server端强制退出时,另一端会报错。。
client端代码
import socket,os from conf import settings def file_cmd(client): while True: msg = input("请输入你想执行的命令(q退出)>>") if msg.lower().strip() == 'q': print('退出成功!') break if not msg: continue if msg.lower().strip() == 'help': print ("请用'put'+'空格'+'文件名'的格式上传文件") print ("请用'get'+'空格'+'文件名'的格式下载文件") print ("输入'dir'查看用户家目录文件") continue if msg.lower().strip() == 'dir': client.send('dir'.encode('utf-8')) data = client.recv(4096) print (data.decode()) continue if msg.lower().strip().startswith('put'): client.send(msg.encode('utf-8')) msg_file, filename = msg.strip().split(' ') filename = os.path.join(settings.CLIENT_HOME,filename) if os.path.exists(filename): print("开始上传文件!") file_size = os.stat(filename).st_size client.send(str(file_size).encode('utf-8')) client.recv(4096) print("开始发送文件...") with open(filename, 'rb') as f: for line in f: client.send(line) print('发送完毕') else: print('文件不存在!') if msg.lower().strip().startswith('get'): client.send(msg.encode('utf-8')) msg_file, filename = msg.strip().split(' ') filename = os.path.join(settings.CLIENT_HOME, filename) file_size = client.recv(4096) if file_size.decode() == 'no': print('文件不存在!') else: client.send('please send file'.encode('utf-8')) file_size_all = int(file_size.decode()) file_size_recv = 0 with open(filename, 'wb') as f: print("开始下载文件!") while file_size_recv < file_size_all: data = client.recv(4096) file_size_recv = len(data) + 1 f.write(data) else: print('文件下载完毕!') def Login(client): while True: name = input("请输入你的用户名(q返回):") if name.lower().strip() == 'q': print('返回上一层成功!') break else: password = input("请输入你的密码:") command = 'login'+' '+ name + ',' + password client.sendall(command.encode('utf-8')) msg = client.recv(4096) if msg.decode() == 'yes': print ("登陆成功!") file_cmd(client) elif msg.decode() == 'no': print ("用户名密码错误,或用户不存在!") else: print ("未知错误!") def Register(client): while True: name = input("请输入你需要注册的用户名(q返回):") if name.lower().strip() == 'q': print('返回上一层成功!') break else: password = input("请输入你要注册的密码:") command = 'register' + ' ' + name + ',' + password client.sendall(command.encode('utf-8')) msg = client.recv(4096) if msg.decode() == 'yes': print("注册成功!") file_cmd(client) elif msg.decode() == 'no': print("用户名已经存在!") else: print("未知错误!") def main(client): while True: menu = """ 1,用户登陆 2,用户注册 3. 退出 """ print (menu) choose = input("请输入索引进行选择:") if choose == '1': Login(client) elif choose == '2': Register(client) elif choose == '3': exit('退出成功!') else: print ("你的选择有误!") def run(): client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect((settings.HOST,settings.PORT)) main(client) client.close()
server端代码
import socket from core.user import User from conf import settings def run(): ftpserver = socket.socket(socket.AF_INET,socket.SOCK_STREAM) ftpserver.bind((settings.HOST,settings.PORT)) ftpserver.listen(5) print ("服务运行中:正在监听{0}地址的{1}端口:".format(settings.HOST,settings.PORT)) while True: conn,addr = ftpserver.accept() while True: data = conn.recv(4096) if not data: break else: print(data) data = data.decode() print(data) if data == 'dir': users.view_file(conn) continue msg, filename = data.strip().split(' ') msg = msg.lower() if msg == 'put': users.Recvfile(conn, filename) elif msg == 'get': re = users.judgement_file(filename) if re == True: users.Sendfile(conn, filename) else: conn.send('no'.encode('utf-8')) elif msg == 'login': name, password = filename.split(',') users = User(name, password) re = users.login() if re == True: conn.send('yes'.encode('utf-8')) else: conn.send('no'.encode('utf-8')) elif msg == 'register': name, password = filename.split(',') print(name,password) users = User(name, password) re = users.register() if re == True: conn.send('yes'.encode('utf-8')) else: conn.send('no'.encode('utf-8')) else: print("请求方的输入有错!")
用户交互代码
import os import json from conf import settings class User(object): def __init__(self,name,password): self.name = name self.password = password self.homedir = os.path.join(settings.USER_HOME,self.name) self.auth = os.path.join(settings.USER_AUTH,self.name) def login(self): if os.path.exists(self.auth): with open(self.auth,'r') as f: user_dict = json.load(f) if user_dict['password'] == self.password: return True else: return False else: return False def register(self): if os.path.exists(self.auth): return False else: os.mkdir(self.homedir) data = {'username': self.name, 'password': self.password} with open(self.auth, 'w') as f: json.dump(data,f) return True def judgement_file(self,filename): filename = os.path.join(self.homedir, filename) if os.path.exists(filename): return True else: return False def view_file(self,conn): data = os.popen('dir'+' '+ self.homedir).read() conn.sendall(data.encode('utf-8')) def Recvfile(self,conn,filename): print("开始接收文件...") filename = os.path.join(self.homedir, filename) file_size = conn.recv(4096) conn.send('please send file'.encode('utf-8')) file_size_all = int(file_size.decode()) file_size_recv = 0 with open(filename, 'wb') as f: print("开始下载文件!") while file_size_recv < file_size_all: data = conn.recv(4096) file_size_recv = len(data) + 1 f.write(data) else: print('文件下载完毕!') def Sendfile(self,conn,filename): filename = os.path.join(self.homedir,filename) file_size = os.stat(filename).st_size conn.send(str(file_size).encode('utf-8')) conn.recv(4096) print("开始发送文件...") with open(filename, 'rb') as f: for line in f: conn.send(line) print('发送完毕')
settings文件
#!/usr/bin/env python # coding=utf-8 #Author:yang import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR_DB = os.path.join(BASE_DIR,'db') USER_HOME = os.path.join(BASE_DIR_DB,'home') USER_AUTH = os.path.join(BASE_DIR_DB,'auth') CLIENT_HOME = os.path.join(BASE_DIR_DB,'client') HOST = 'localhost' PORT = 9999