1018 作业
FTP:
- 注册(每个用户都有自己的一个自己的目录,可以用户名命名)
- 登录(每个用户登录成功后,进入当前用户的目录)
- 上传电影或普通文件,客户端可以选择上传的电影,保存到当前用户目录下
- 用户可在自己的目录下选择需要下载的普通文件或电影
下面的作业是未完善未优化的,很多文件没有分开,需要手动建立db , file 两个文件夹 , 但是功能大部分还是实现了,等我知识扩展了再来改。
文件目录
-------ftp 总文件夹
----db 存放用户信息
----file 存放用户个人目录
-client.py
-server.py
# server.py
import socketserver,struct,json,os
class MyTcpServer(socketserver.BaseRequestHandler):
def handle(self):
flg = self.request.recv(1).decode('utf8')
if flg == 'u':
headers = self.request.recv(4)
data_len = struct.unpack('i', headers)[0]
bytes_data = self.request.recv(data_len)
back_dic = json.loads(bytes_data.decode('utf-8'))
print(back_dic)
file_path = back_dic.get('file_path')
file_name = back_dic.get('file_name')
file_size = back_dic.get('file_size')
init_data = 0
f_path = os.path.join(file_path, file_name)
with open(f_path, 'wb') as f:
while init_data < file_size:
data = self.request.recv(1024)
f.write(data)
init_data += len(data)
send_msg = f'{file_name}接收完毕!'.encode('utf-8')
self.request.send(send_msg)
elif flg == 'd':
headers = self.request.recv(4)
data_len = struct.unpack('i', headers)[0]
bytes_data = self.request.recv(data_len)
back_dic = json.loads(bytes_data.decode('utf-8'))
print(back_dic)
file_path = back_dic.get('file_path')
with open(file_path, 'rb') as f:
file_content = f.read()
self.request.send(file_content)
def run():
socketserver.TCPServer.allow_reuse_address = True
server = socketserver.TCPServer(
('127.0.0.1', 8888), MyTcpServer
)
server.serve_forever()
if __name__ == '__main__':
run()
# client.py
import os,socket, struct, json
BASE_PATH = os.path.dirname(__file__)
DB_PATH = os.path.join(BASE_PATH, 'db')
F_PATH = os.path.join(BASE_PATH, 'file')
user_info = {
'user': None
}
def register():
while True:
username = input('请输入用户名>>:').strip()
password = input('请输入密码>>:').strip()
user_path = os.path.join(DB_PATH, f'{username}')
if os.path.exists(user_path):
print('该用户已存在')
break
else:
user_dic = {
'username': username,
'password': password
}
with open(user_path, 'w', encoding='utf8') as f:
json.dump(user_dic, f)
file_path = os.path.join(F_PATH, f'{username}')
os.mkdir(file_path)
print('注册成功,已创建个人目录')
break
def login():
while True:
username = input('请输入用户名>>:').strip()
password = input('请输入密码>>:').strip()
user_path = os.path.join(DB_PATH, f'{username}')
if not os.path.exists(user_path):
print('该用户不存在,请先注册')
break
with open(user_path, 'r', encoding='utf8') as f:
user_dic = json.load(f)
if password == user_dic.get('password'):
print('登录成功')
user_info['user'] = username
break
else:
print('密码错误')
continue
def check_dir():
while True:
if user_info.get('user'):
username = user_info.get('user')
file_path = os.path.join(F_PATH, username)
lis = os.listdir(file_path)
if lis:
print(lis)
return lis
else:
print(f'{username} 个人目录下没有文件,请上传文件')
break
else:
print('未登录,请先登录')
break
def upload():
client = socket.socket()
client.connect(
('127.0.0.1', 8888)
)
while True:
if not user_info.get('user'):
print('请先登录')
break
file_path = input('请输入上传的文件路径 输入q 退出>>:').strip()
if file_path == 'q':
break
if not file_path.startswith('D'or'E'or'C'or'F'):
print('输入错误')
continue
file_name = input('请输入上传的文件名>>:').strip()
with open(f'{file_path}', 'rb') as f:
movie_bytes = f.read()
username = user_info.get('user')
file1_path = os.path.join(F_PATH, f'{username}')
send_dic = {
'file_path': file1_path,
'file_name': file_name,
'file_size': len(movie_bytes)}
json_data = json.dumps(send_dic)
bytes_data = json_data.encode('utf-8')
headers = struct.pack('i', len(bytes_data))
flg = 'u'
client.send(flg.encode('utf-8'))
client.send(headers)
client.send(bytes_data)
init_data = 0
num = 1
with open(f'{file_path}', 'rb') as f:
while init_data < len(movie_bytes):
send_data = f.read(1024)
print(send_data, num)
num += 1
client.send(send_data)
init_data += len(send_data)
from_server_data = client.recv(1024).decode("utf-8")
print(from_server_data)
def download():
client = socket.socket()
client.connect(
('127.0.0.1', 8888)
)
while True:
if not user_info.get('user'):
print('请先登录')
break
check_dir()
file_name = input('请输入下载的文件名>>:').strip()
username = user_info.get('user')
file_path = os.path.join(F_PATH, f'{username}')
deep = os.path.join(file_path,file_name)
with open(f'{deep}', 'rb') as f:
movie_bytes = f.read()
send_dic = {
'file_path': deep,
'file_name': file_name,
'file_size': len(movie_bytes)}
json_data = json.dumps(send_dic)
bytes_data = json_data.encode('utf-8')
headers = struct.pack('i', len(bytes_data))
flg = 'd'
client.send(flg.encode('utf-8'))
client.send(headers)
client.send(bytes_data)
data = client.recv(len(movie_bytes))
file_name = input('下载保存的文件名>>')
with open(file_name, "wb") as f:
f.write(data)
print("下载成功,请查看!")
break
func_dic = {
'1': register,
'2': login,
'3': check_dir,
'4': upload,
'5': download
}
def run():
while True:
print('''
1 注册
2 登录
3 查看个人目录
4 上传个人文件
5 下载个人文件
q 退出
''')
choice = input('请选择功能>>').strip()
if choice == 'q':
break
if choice not in func_dic:
print('输入错误')
continue
func_dic.get(choice)()
if __name__ == '__main__':
run()