题目要求
用户加密认证
允许同时多用户登录
每个用户有自己的家目录
允许用户在ftp server上随意切换目录
允许用户查看当前目录下文件
允许上传和下载文件,保证文件一致性
代码
server端
#!/usr/bin/env python3
import socketserver,os,pickle,hashlib
class MyServer(socketserver.BaseRequestHandler):
def put(self, file_list):
for file_name in file_list:
file_name += "server"
with open(file_name, 'w') as f:
pass
while True:
flag = str(self.request.recv(1024), encoding = "utf8") #接收客户端开始的消息
if flag == "start":
self.request.send(bytes("succ", encoding = "utf8")) #通知客户端成功
else:
self.request.send(bytes("err", encoding = "utf8")) #通知客户端失败
break
len_data = int(str(self.request.recv(1024), encoding = "utf8")) #接收长度
self.request.send(bytes("长度接收成功", encoding = "utf8"))
data = ''
while len(data) < int(len_data):
a = str(self.request.recv(1245),encoding = "utf8") #拼接传输的数据
data += a
print(data,end = '')
with open(file_name, 'a') as f:
f.write(data)
def get(self, file_list):
for file_name in file_list:
with open(file_name, "r") as f:
for i in f:
self.request.sendall(bytes("start", encoding = "utf8"))
self.succ_info_1 = str(self.request.recv(1024), encoding = "utf8")
self.len_data = len(i)
print(self.len_data) #显示文件的长度
#服务端在发送数据的时候,不能直接发数字,不然接收端变量类型会不好处理,最好以字符串的形式再用encode编码,在这里用str(xxx, encoding = "utf8"会报错)
self.request.sendall(str(self.len_data).encode())
self.succ_info_2 = str(self.request.recv(1024), encoding = "utf8") #接收客户端确认接收的信息
print(self.succ_info_2)
self.request.send(bytes(i, encoding = "utf8")) #发送文件中的数据
else:
self.request.sendall(bytes("end", encoding = "utf8")) #发送结束传输的信息
self.request.recv(1024)
def cd(self, cd_dir):
os.chdir(cd_dir[0])
def pwd(self):
print('start pwd')
self.request.sendall(bytes(os.getcwd(), encoding = 'utf8'))
def ls(self):
dir_list = os.popen('ls').read()
#self.request.sendall(bytes(dir_list, encoding = 'utf8'))
len_dir_list = len(dir_list)
self.request.send(str(len_dir_list).encode())
len_dir_list_succ = str(self.request.recv(1024), encoding = "utf8")
self.request.send(bytes(dir_list, encoding = "utf8"))
#def by(self):
# exit()
def get_cmd(self):
#存储各个功能的字典
self.cmd_dict = {
'get':self.get,
'put':self.put,
'cd':self.cd,
'pwd':self.pwd,
'ls':self.ls,
#'by':self.by,
}
while True:
self.get_cmd_data = str(self.request.recv(1024), encoding = "utf8") #接收命令
print(self.get_cmd_data)
self.cmd_list = self.get_cmd_data.split() #将指令与用户分开
if len(self.cmd_list) > 1:
self.cmd_dict[self.cmd_list[0]](self.cmd_list[1:]) #执行命令
else:
self.cmd_dict[self.cmd_list[0]]()
def user_login(self):
f = open('/home/dy/python_test/Day07/homework/user_passwd', 'rb')
self.user_list = pickle.load(f)
f.close()
print(self.user_list)
self.login_stat = False
self.request.send(bytes("请输入用户名:", encoding = "utf8"))
user_name = str(self.request.recv(1024), encoding = 'utf8')
self.request.send(bytes("请输入密码:", encoding = "utf8"))
user_password = self.request.recv(1024)
text = hashlib.sha256()
text.update(user_password)
user_password = text.hexdigest()
if self.user_list[user_name] == user_password:
if not os.path.exists('/home/dy/python_test/Day07/homework/%s' % user_name):
os.makedirs('/home/dy/python_test/Day07/homework/%s' % user_name)
os.chdir('/home/dy/python_test/Day07/homework/%s' % user_name)
self.login_stat = True
def handle(self):
print('server start ...')
self.user_login()
if self.login_stat:
while True:
self.get_cmd()
if __name__ == "__main__":
ip,port = '127.0.0.1', 28888
server = socketserver.ThreadingTCPServer((ip, port), MyServer)
server.serve_forever()
client端
#!/usr/bin/env python3
import socket,os,getpass
def get_file(file_list):
for file_name in file_list:
file_name += "client"
with open(file_name, 'w') as f:
pass
while True:
flag = str(client.recv(1024), encoding = "utf8") #接收服务端开始的消息
if flag == "start":
client.send(bytes("succ", encoding = "utf8")) #通知服务端成功
else:
client.send(bytes("err", encoding = "utf8")) #通知服务端失败
break
len_data = int(str(client.recv(1024), encoding = "utf8")) #接收长度
client.send(bytes("长度接收成功", encoding = "utf8"))
data = ''
while len(data) < int(len_data):
a = str(client.recv(1245),encoding = "utf8") #拼接传输的数据
data += a
print(data,end = '')
with open(file_name, 'a') as f:
f.write(data)
def put_file(file_list):
for file_name in file_list:
with open(file_name, "r") as f:
for i in f:
client.sendall(bytes("start", encoding = "utf8"))
succ_info_1 = str(client.recv(1024), encoding = "utf8")
len_data = len(i)
print(len_data) #显示文件的长度
#服务端在发送数据的时候,不能直接发数字,不然接收端变量类型会不好处理,最好以字符串的形式再用encode编码,在这里用str(xxx, encoding = "utf8"会报错)
client.sendall(str(len_data).encode())
succ_info_2 = str(client.recv(1024), encoding = "utf8") #接收客户端确认接收的信息
print(succ_info_2)
client.send(bytes(i, encoding = "utf8")) #发送文件中的数据
else:
client.sendall(bytes("end", encoding = "utf8")) #发送结束传输的信息
client.recv(1024)
def pwd():
server_dir = str(client.recv(2048), encoding = 'utf8')
print(server_dir)
def ls():
dir_list_len = int(str(client.recv(1024), encoding = "utf8"))
client.send(bytes("长度接收成功", encoding = "utf8"))
#print("dir_list:",len(dir_list))
#print("dir_list_len",dir_list_len)
dir_list = ''
while len(dir_list) < dir_list_len:
dir_list += str(client.recv(1024), encoding = "utf8")
print(dir_list)
def by():
exit()
def send_cmd():
user_cmd_dict = {
'get':get_file,
'put':put_file,
'pwd':pwd,
'ls':ls,
'by':by,
}
while True:
user_input = input("请输入命令:")
if user_input:break
client.send(bytes(user_input, encoding = "utf8"))
user_cmd_list = user_input.split()
if (user_cmd_list[0] in ['put', 'get', ]) and (len(user_cmd_list) > 1) :
user_cmd_dict[user_cmd_list[0]](user_cmd_list[1:])
elif user_cmd_list[0] in ['pwd', 'ls', 'by'] :
user_cmd_dict[user_cmd_list[0]]()
def user_login():
title_name = str(client.recv(1024), encoding = "utf8")
print(title_name)
send_name = input()
client.send(bytes(send_name, encoding = 'utf8'))
title_passwd = str(client.recv(1024), encoding = 'utf8')
print(title_passwd)
send_passwd = getpass.getpass()
client.send(bytes(send_passwd, encoding = 'utf8'))
if __name__ == '__main__':
ip_port = ('127.0.0.1', 28888)
client = socket.socket()
client.connect(ip_port)
user_login()
while True:
send_cmd()
添加用户脚本
#!/usr/bin/env python3
import hashlib, pickle
user_name = input("请输入用户名")
user_password = input("请输入密码")
text = hashlib.sha256()
text.update(bytes(user_password, encoding = "utf8"))
user_password = text.hexdigest()
with open("user_passwd", "rb") as f:
user_list = pickle.load(f)
user_list[user_name] = user_password
with open("user_passwd", "wb") as f:
pickle.dump(user_list, f)
用户文件初始化脚本
#!/usr/bin/env python3
import pickle
a = {}
with open("user_passwd", "wb") as f:
pickle.dump(a, f)