作业
FTP:
- 1.注册(每个用户都有自己的一个自己的目录,可以用户名命名)
- 2.登录(每个用户登录成功后,进入当前用户的目录)
- 3.上传电影或普通文件,客户端可以选择上传的电影,保存到当前用户目录下
- 4.用户可在自己的目录下选择需要下载的普通文件或电影
# 客户端.py
import socket
import json
import struct
import os
login_user = {
'user_name': None
}
def regeist(client):
'''注册'''
user_name = input('用户名:').strip()
user_pwd = input('密码:').strip()
re_pwd = input('确认密码:').strip()
if re_pwd != user_pwd:
print('确认密码错误')
return
user_dic = {'user_name': user_name, 'user_pwd': user_pwd}
user_dic_json = json.dumps(user_dic)
user_bytes_data = user_dic_json.encode('utf-8')
headers_info = {'function': 'regeist', 'bytes_size': len(user_bytes_data)}
headers_info_json = json.dumps(headers_info)
headers_bytes_data = headers_info_json.encode('utf-8')
headers = struct.pack('i', len(headers_bytes_data))
client.send(headers)
client.send(headers_bytes_data)
client.send(user_bytes_data)
result = client.recv(1024).decode('utf-8') # 注册成功True,或失败False
print(result)
def login(client):
'''登陆'''
user_name = input('用户名:').strip()
user_pwd = input('密码:').strip()
user_dic = {'user_name': user_name, 'user_pwd': user_pwd}
user_dic_json = json.dumps(user_dic)
user_bytes_data = user_dic_json.encode('utf-8')
headers_info = {'function': 'login', 'bytes_size': len(user_bytes_data)}
headers_info_json = json.dumps(headers_info)
headers_bytes_data = headers_info_json.encode('utf-8')
headers = struct.pack('i', len(headers_bytes_data))
client.send(headers)
client.send(headers_bytes_data)
client.send(user_bytes_data)
result = client.recv(1024).decode('utf-8') # 注册成功True,或失败False
print(result)
if result == '登陆成功':
login_user['user_name'] = user_name
def upload(client, file_path):
# 打开文件
file_name = os.path.basename(file_path)
if file_path.endswith('txt') or file_path.endswith('pdf') or file_path.endswith('md'):
print('上传文档')
with open(file_path, 'r', encoding='utf-8') as fr:
file_bytes_data = fr.read().encode('utf_8')
else:
print('上传视频或者图片')
with open(file_path, 'rb') as fr:
file_bytes_data = fr.read()
headers_info = {'function': 'upload', 'bytes_size': len(file_bytes_data), 'file_name': file_name,
'user_name': login_user.get('user_name')}
headers_info_json = json.dumps(headers_info)
headers_bytes_data = headers_info_json.encode('utf-8')
headers = struct.pack('i', len(headers_bytes_data))
client.send(headers)
client.send(headers_bytes_data)
client.send(file_bytes_data)
result = client.recv(1024).decode('utf-8')
print(result)
def download(client, file_name):
headers_info = {'function': 'download', 'file_name': file_name, 'user_name': login_user.get('user_name')}
headers_info_json = json.dumps(headers_info)
headers_bytes_data = headers_info_json.encode('utf-8')
headers = struct.pack('i', len(headers_bytes_data))
client.send(headers)
client.send(headers_bytes_data)
headers = client.recv(4)
bytes_size = struct.unpack('i', headers)[0]
file_data_bytes = client.recv(bytes_size)
if not os.path.isdir('local_file'):
os.mkdir('local_file')
file_path = os.path.join('local_file', file_name)
if file_name.endswith('txt') or file_name.endswith('pdf') or file_name.endswith('md'):
print(f'下载文档:{file_name}')
with open(file_path, 'w', encoding='utf-8') as fw:
fw.write(file_data_bytes.decode('utf-8'))
else:
print(f'下载音频:{file_name}')
with open(file_path, 'wb') as fw:
fw.write(file_data_bytes)
print('下载保存成功')
def get_file_list(client,user_name):
headers_info = {'function': 'get_file_list', 'user_name': user_name}
headers_info_json = json.dumps(headers_info)
headers_bytes_data = headers_info_json.encode('utf-8')
headers = struct.pack('i',len(headers_bytes_data))
client.send(headers)
client.send(headers_bytes_data) # 发起获取文件列表请求
headers = client.recv(4) # 接收报文,文件列表的字节数
date_length = struct.unpack('i', headers)[0]
file_list_json = client.recv(date_length).decode('utf-8')
file_list = json.loads(file_list_json)
return file_list
client = socket.socket()
client.connect(('127.0.0.1', 9587))
while not login_user.get('user_name'):
func_dic = {
'1': regeist,
'2': login
}
print('''
1 注册
2 登陆
q 退出''')
choice = input('选择:').strip()
if choice == 'q':
break
if choice not in func_dic:
print('请输入正确编号')
continue
func_dic[choice](client)
# 登陆成功
while True:
file_list = get_file_list(client, login_user.get('user_name'))
print('=' * 20)
for i in range(len(file_list)):
print(i, file_list[i])
print('=' * 20)
choice = input('''
1 上传文件
2 下载文件
q 退出''')
if choice == 'q':
break
if choice == '1':
while True:
file_name = input('请输入文件名:')
if not os.path.exists(file_name):
print('文件不存在')
continue
upload(client, file_name)
break
elif choice == '2':
while True:
file_num = input('下载文件编号:').strip()
if not file_num.isdigit():
print('请输入数字')
continue
file_num = eval(file_num)
if file_num not in range(len(file_list)):
print('请输入正确的编号')
continue
file_name = file_list[file_num]
download(client, file_name)
break
import socket
import json
import struct
import os
def regeist(conn, bytes_size=None, file_name=None, user_name=None):
'''注册'''
user_dic_json = conn.recv(bytes_size).decode('utf-8')
user_dic = json.loads(user_dic_json)
user_name = user_dic.get('user_name')
user_pwd = user_dic.get('user_pwd')
dir_path = user_name
if os.path.isdir(dir_path):
print('用户名已存在')
conn.send('用户名已存在'.encode('utf-8'))
return
# 创建用户目录
os.mkdir(dir_path)
conn.send('注册成功'.encode('utf-8'))
print('注册成功')
# 保存注册信息
user_dir = 'user_info'
if not os.path.isdir(user_dir):
os.mkdir(user_dir)
user_list = os.listdir(dir_path)
if user_name not in user_list:
with open(os.path.join(user_dir, f'{user_name}.json'), 'w', encoding='utf-8') as fw:
json.dump(user_dic, fw)
def login(conn, bytes_size=None, file_name=None, user_name=None):
user_dic_json = conn.recv(bytes_size).decode('utf-8')
user_dic = json.loads(user_dic_json)
user_name = user_dic.get('user_name')
user_pwd = user_dic.get('user_pwd')
file_path = os.path.join('user_info', f'{user_name}.json')
if not os.path.isfile(file_path):
conn.send('用户不存在'.encode('utf-8'))
return
with open(file_path, 'r', encoding='utf-8') as fr:
user_dic_in_server = json.load(fr)
if user_name != user_dic_in_server.get('user_name') or user_pwd != user_dic_in_server.get('user_pwd'):
conn.send('密码错误'.encode('utf-8'))
return
conn.send('登陆成功'.encode('utf-8'))
# send_file_list(user_name)
def get_file_list(conn, bytes_size=None, file_name=None, user_name=None):
file_list = os.listdir(user_name)
print(file_list)
file_list_json = json.dumps(file_list)
data_bytes = file_list_json.encode('utf-8')
headers = struct.pack('i', len(data_bytes))
conn.send(headers)
conn.send(data_bytes)
def upload(conn, bytes_size=None, file_name=None, user_name=None):
file_path = os.path.join(user_name, file_name)
file_data_bytes = conn.recv(bytes_size)
if file_name.endswith('txt') or file_name.endswith('pdf') or file_name.endswith('md'):
file_data = file_data_bytes.decode('utf-8')
with open(file_path, 'w', encoding='utf-8') as fw:
fw.write(file_data)
print('上传保存成功')
else:
with open(file_path, 'wb') as fw:
fw.write(file_data_bytes)
print('上传保存成功')
conn.send('上传保存成功'.encode('utf-8'))
def download(conn, bytes_size=None, file_name=None, user_name=None):
file_path = os.path.join(user_name, file_name)
if file_name.endswith('txt') or file_name.endswith('pdf') or file_name.endswith('md'):
with open(file_path, 'r', encoding='utf-8') as fr:
file_data_bytes = fr.read().encode('utf-8')
else:
with open(file_path, 'rb') as fr:
file_data_bytes = fr.read()
headers = struct.pack('i', len(file_data_bytes))
conn.send(headers)
conn.send(file_data_bytes)
print('下发成功')
func_dic = {
'regeist': regeist,
'login': login,
'upload': upload,
'download': download,
'get_file_list':get_file_list
}
server = socket.socket()
server.bind(('127.0.0.1', 9587))
server.listen(5)
while True:
conn, addr = server.accept()
while True:
try:
headers = conn.recv(4)
headers_info_length = struct.unpack('i', headers)[0]
headers_info_json = conn.recv(headers_info_length).decode('utf-8')
headers_info = json.loads(headers_info_json)
function_name = headers_info.get('function')
bytes_size = headers_info.get('bytes_size')
file_name = headers_info.get('file_name')
user_name = headers_info.get('user_name')
print(function_name)
func_dic[function_name](conn, bytes_size, file_name, user_name)
except Exception as e:
print(f'e:{e}')
break
conn.close()