题目要求:
# 1.登录 + 文件下载
# 用户必须登录才能下载
# 用户是否登录应该记录在服务器
# 并且用户可以自己选择 上传 还是 下载
# server.py
import socketserver
import struct
import json
import os
BASE_PATH = os.path.dirname(__file__)
REGISTER_PATH = 'register'
Login_User = None
User_path = ''
class Myserver(socketserver.BaseRequestHandler):
def handle(self):
conn = self.request
for i in range(3):
b_length = conn.recv(4)
length = struct.unpack('i', b_length)[0]
s_dic = conn.recv(length).decode('utf-8')
login_dic = json.loads(s_dic)
with open(REGISTER_PATH, encoding='utf-8', mode='rt') as file_handler:
for line in file_handler:
username, password = line.strip().split('|')
if login_dic['username'] == username and login_dic['password'] == password:
conn.send('login success.'.encode('utf-8'))
global Login_User
Login_User = login_dic['username']
if not os.path.isdir(os.path.join(BASE_PATH, Login_User)):
os.mkdir(os.path.join(BASE_PATH, Login_User))
User_path = os.path.join(BASE_PATH, Login_User)
break
if Login_User is None:
conn.send('login failed.'.encode('utf-8'))
if Login_User:
while True:
mode = conn.recv(1).decode('utf-8')
if mode == '1': # 上传
b_length = conn.recv(4)
length = struct.unpack('i', b_length)[0]
b_file_dic = conn.recv(length)
file_dic = json.loads(b_file_dic)
with open(os.path.join(User_path, file_dic['filename']), mode='wb') as file_handler:
while file_dic['filesize'] > 0:
content = conn.recv(1024)
file_dic['filesize'] -= len(content)
file_handler.write(content)
if file_dic['filesize'] == 0:
conn.send('True'.encode('utf-8'))
else: conn.send('False'.encode('utf-8'))
if mode == '2': # 下载
obj = os.walk(User_path)
_, _, file_list = obj.__next__()
# print(file_list)
s_file_list = json.dumps(file_list)
b_length = struct.pack('i', len(s_file_list))
conn.send(b_length)
conn.send(s_file_list.encode('utf-8'))
b_length = conn.recv(4)
length = struct.unpack('i', b_length)[0]
filename = conn.recv(length).decode('utf-8')
filesize = os.path.getsize(os.path.join(User_path, filename))
file_dic = {'filename': filename, 'filesize': filesize}
b_file_dic = json.dumps(file_dic).encode('utf-8')
b_length = struct.pack('i', len(b_file_dic))
conn.send(b_length)
conn.send(b_file_dic)
with open(os.path.join(User_path, file_dic['filename']), mode='rb') as file_handler:
while file_dic['filesize'] > 0:
content = file_handler.read(1024)
file_dic['filesize'] -= len(content)
conn.send(content)
if mode == '3':
conn.close()
break
server = socketserver.ThreadingTCPServer(('127.0.0.1', 9000), Myserver)
server.serve_forever()
# client.py
import socket
import struct
import json
import os
BASE_PATH = os.path.dirname(__file__)
User = None
User_path = ''
sk = socket.socket()
sk.connect(('127.0.0.1', 9000))
for i in range(3):
username = input('username>>>')
password = input('password>>>')
login_dic = {'username': username, 'password': password}
s_dic = json.dumps(login_dic)
b_length = struct.pack('i', len(s_dic))
sk.send(b_length)
sk.send(s_dic.encode('utf-8'))
ret = sk.recv(1024).decode('utf-8')
print(ret)
if ret == 'login success.':
User = username
User_path = os.path.join(BASE_PATH, User)
if not os.path.isdir(User_path):
os.mkdir(User_path)
break
if User:
while True:
print('1.上传文件')
print('2.下载文件')
print('3.退出程序')
mode = input('PLS select ur mode.>>>')
if mode.isdecimal():
if mode == '1':
sk.send(mode.encode('utf-8'))
while True:
path = input('Pls input ur absolute path.>>>')
if os.path.isfile(path):
filename = os.path.basename(path)
filesize = os.path.getsize(path)
file_dic = {'filename': filename, 'filesize': filesize}
s_dic = json.dumps(file_dic)
b_length = struct.pack('i', len(s_dic))
sk.send(b_length)
sk.send(s_dic.encode('utf-8'))
with open(path, mode='rb') as file_handler:
while file_dic['filesize'] > 0:
content = file_handler.read(1024)
file_dic['filesize'] -= len(content)
sk.send(content)
print(sk.recv(1024).decode('utf-8'))
break
elif mode == '2':
sk.send(mode.encode('utf-8'))
b_length = sk.recv(4)
length = struct.unpack('i', b_length)[0]
s_file_list = sk.recv(length).decode('utf-8')
file_list = json.loads(s_file_list)
for num, filename in enumerate(file_list, 1):
print(num, filename)
b_download_filename = input('Pls input ur download filename.>>>').encode('utf-8')
b_length = struct.pack('i', len(b_download_filename))
sk.send(b_length)
sk.send(b_download_filename)
b_length = sk.recv(4)
length = struct.unpack('i', b_length)[0]
s_file_dic = sk.recv(length).decode('utf-8')
file_dic = json.loads(s_file_dic)
with open(os.path.join(User_path, file_dic['filename']), mode='wb') as file_handler:
while file_dic['filesize'] > 0:
content = sk.recv(1024)
file_dic['filesize'] -= len(content)
file_handler.write(content)
if file_dic['filesize'] == 0:
print('Download success.')
elif mode == '3':
sk.send(mode.encode('utf-8'))
sk.close()
break
else:
print('Illegal input.')
else: print('Illegal input.')