客户端
core文件夹
from lib import common from conf import setting import os userinfo = {'cookies': None} def register(client): while True: username = input('请输入用户名:').strip() password = input('请输入密码:').strip() re_password = input('请确认密码:').strip() if password == re_password: send_dic = { 'username': username, 'password': password, 'user_type': 'admin', 'func_type': 'register' } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): print(back_dic.get('msg')) break else: print(back_dic.get('msg')) else: print('两次密码不一致!!!') continue def login(client): while True: username = input('请输入用户名:').strip() password = input('请输入密码:').strip() send_dic = { 'username': username, 'password': password, 'func_type': 'login' } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): print(back_dic.get('msg')) userinfo['cookies'] = back_dic.get('session') break else: print(back_dic.get('msg')) def upload_movie(client): while True: upload_movie_dir = setting.UPLOAD_MOVIE_PATH movie_list = os.listdir(upload_movie_dir) if not movie_list: print('没有电影可以上传') break for index, movie_name in enumerate(movie_list): print(index, movie_name) choice = input('请输入电影编号或q退出:').strip() if choice == 'q': break if not choice.isdigit(): print('请输入数字!!!') continue choice = int(choice) if choice not in range(len(movie_list)): print('请输入编号内数字!!!') continue movie_name = movie_list[choice] movie_path = os.path.join(upload_movie_dir, movie_name) movie_size = os.path.getsize(movie_path) movie_md5 = common.get_movie_md5(movie_path) send_dic = { 'func_type': 'check_movie', 'movie_md5': movie_md5, 'cookies': userinfo.get('cookies') } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): choice2 = input('请输入是否是收费的(y or n):').strip() is_free = 0 if choice2 == 'y': is_free = 1 send_dic2 = { 'func_type': 'upload_movie', 'movie_md5': movie_md5, 'cookies': userinfo.get('cookies'), 'movie_name': movie_name, 'movie_size': movie_size, 'is_free': is_free } back_dic2 = common.send_and_back(send_dic2, client, file=movie_path) if back_dic2.get('flag'): print(back_dic2.get('msg')) break else: print(back_dic.get('msg')) def delete_movie(client): while True: send_dic = { 'func_type': 'get_movie_list', 'cookies': userinfo.get('cookies'), 'movie_type': 'all' } back_dic = common.send_and_back(send_dic, client) if not back_dic.get('flag'): print(back_dic.get('msg')) break movie_list = back_dic.get('movie_list') for index, movie_name_id in enumerate(movie_list): print(index, movie_name_id) if not movie_list: print('没有可删除的电影了') break choice = input('请输入需要删除的电影编号或q退出:').strip() if choice == 'q': break if not choice.isdigit(): continue choice = int(choice) if choice not in range(len(movie_list)): continue movie_name_id = movie_list[choice] send_dic = { 'func_type': 'delete_movie', 'cookies': userinfo.get('cookies'), 'movie_id': movie_name_id[1] } back_dic2 = common.send_and_back(send_dic, client) if back_dic2.get('flag'): print(back_dic2.get('msg')) break def send_notice(client): title = input('请输入公告标题:').strip() content = input('请输入公告内容:').strip() send_dic = { 'title': title, 'content': content, 'cookies': userinfo.get('cookies'), 'func_type': 'send_notice' } back_dic = common.send_and_back(send_dic, client) print(back_dic.get('msg')) func_dic = { '1': register, '2': login, '3': upload_movie, '4': delete_movie, '5': send_notice, } def admin_view(client): 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[choice](client)admin.py
from lib import common from conf import setting import time import os user_info = {'cookies': None, 'is_vip': 0} def register(client): while True: username = input('请输入用户名:').strip() password = input('请输入密码:').strip() re_password = input('请确认密码:').strip() if password == re_password: send_dic = { 'username': username, 'password': password, 'user_type': 'user', 'func_type': 'register' } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): print(back_dic.get('msg')) break else: print(back_dic.get('msg')) def login(client): while True: username = input('请输入用户名:').strip() password = input('请输入密码:').strip() send_dic = { 'func_type': 'login', 'username': username, 'password': password } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): print(back_dic.get('msg')) user_info['cookies'] = back_dic.get('session') is_vip = back_dic.get('is_vip') if is_vip: user_info['is_vip'] = is_vip break else: print(back_dic.get('msg')) def buy_vip(client): if not user_info.get('is_vip'): choice = input('请输入y确认冲会员(会员费10000元),输入其他键退出:').strip() if choice == 'y': send_dic = { 'cookies': user_info.get('cookies'), 'func_type': 'buy_vip' } back_dic = common.send_and_back(send_dic, client) print(back_dic.get('msg')) login(client) else: print('穷b!!!') else: print('您已经是会员了') def check_movies(client): send_dic = { 'func_type': 'get_movie_list', 'movie_type': 'all', 'cookies': user_info.get('cookies') } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): print(back_dic.get('movie_list')) else: print(back_dic.get('msg')) def download_free_movie(client): while True: send_dic = { 'func_type': 'get_movie_list', 'movie_type': 'free', 'cookies': user_info.get('cookies') } back_dic = common.send_and_back(send_dic, client) if not back_dic.get('flag'): print(back_dic.get('msg')) break movie_list = back_dic.get('movie_list') if not movie_list: print('没有可下载的免费的电影') break for index, movie_id_name in enumerate(movie_list): print(index, movie_id_name) choice = input('请输入要下载的电影编号').strip() if not choice.isdigit(): print('请输入数字') continue choice = int(choice) if choice not in range(len(movie_list)): print('请输入编范围内的数字') continue movie_name, movie_id, movie_type = movie_list[choice] send_dic2 = { 'cookies': user_info.get('cookies'), 'func_type': 'download_movie', 'movie_id': movie_id, 'movie_name': movie_name } back_dic2 = common.send_and_back(send_dic2, client) wait_time = back_dic2.get('wait_time') if wait_time: print('广告时间10s') time.sleep(wait_time) movie_size = back_dic2.get('movie_size') movie_path = os.path.join(setting.DOWNLOAD_MOVIE_PATH, movie_name) recv_data = 0 with open(movie_path, 'wb') as f: while recv_data < movie_size: data = client.recv(1024) f.write(data) recv_data += len(data) break def download_pay_movie(client): while True: send_dic = { 'cookies': user_info.get('cookies'), 'func_type': 'get_movie_list', 'movie_type': 'pay' } back_dic = common.send_and_back(send_dic, client) if not back_dic.get('flag'): print(back_dic.get('msg')) break movie_list = back_dic.get('movie_list') if not movie_list: print('没有可下载的电影') break for index, movie_name_id in enumerate(movie_list): print(index, movie_name_id) choice = input('请输入y确认购买电影(会员:200元,普通用户800元),输入其他退出:').strip() if choice == 'y': if user_info.get('is_vip'): print('会员购买电影成功,开始选择电影...') else: print('普通用户购买电影成功,开始选择电影...') else: print('穷b, 没钱还想看电影,滚犊子吧') break choice2 = input('请输入需要下载电影的编号:').strip() if not choice2.isdigit(): continue choice2 = int(choice2) if choice2 not in range(len(movie_list)): continue movie_name, movie_id, movie_type = movie_list[choice2] send_dic2 = { 'cookies': user_info.get('cookies'), 'func_type': 'download_movie', 'movie_name': movie_name, 'movie_id': movie_id } back_dic2 = common.send_and_back(send_dic2, client) movie_size = back_dic2.get('movie_size') movie_path = os.path.join(setting.DOWNLOAD_MOVIE_PATH, movie_name) recv_data = 0 with open(movie_path, 'wb') as f: while recv_data < movie_size: data = client.recv(1024) f.write(data) recv_data += len(data) break def check_download_record(client): send_dic = { 'func_type': 'check_download_record', 'cookies': user_info.get('cookies') } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): print(back_dic.get('download_movie_list')) else: print(back_dic.get('msg')) def check_notice(client): send_dic = { 'func_type': 'check_notice', 'cookies': user_info.get('cookies') } back_dic = common.send_and_back(send_dic, client) if back_dic.get('flag'): print(back_dic.get('notice_list')) else: print(back_dic.get('msg')) func_dic = { '1': register, '2': login, '3': buy_vip, '4': check_movies, '5': download_free_movie, '6': download_pay_movie, '7': check_download_record, '8': check_notice } def user_view(client): while True: print(''' 1 注册 2 登录 3 冲会员 4 查看视频 5 下载免费视频 6 下载收费视频 7 查看下载记录 8 查看公告 q 退出 ''') choice = input('请输入功能编号:').strip() if choice == 'q': break if choice not in func_dic: continue func_dic[choice](client)user.py
lib文件夹
import struct import hashlib import json import os def send_and_back(send_dic, client, file=None): # 发送报头和真实数据 json_bytes = json.dumps(send_dic).encode('utf-8') header = struct.pack('i', len(json_bytes)) client.send(header) client.send(json_bytes) if file: with open(file, 'rb') as f: for i in f: client.send(i) # 接收服务端返回的数据 headers = client.recv(4) bytes_len = struct.unpack('i', headers)[0] json_bytes_data = client.recv(bytes_len).decode('utf8') back_dic = json.loads(json_bytes_data) return back_dic def get_movie_md5(movie_path): movie_size = os.path.getsize(movie_path) index_list = [0, movie_size//3, (movie_size//3)*2, movie_size-10] md5_obj = hashlib.md5() with open(movie_path, 'rb') as f: for line in index_list: f.seek(line) data = f.read(10) md5_obj.update(data) return md5_obj.hexdigest()common.py
服务端
interface文件夹
from db.models import Movie from db.models import Notice import datetime from lib import common from threading import Lock from conf import setting import os mutex = Lock() @common.login_auth def check_movie_interface(back_dic, conn): movie_md5 = back_dic.get('movie_md5') movie_obj_list = Movie.select_data(movie_md5=movie_md5) if movie_obj_list: send_dic = { 'flag': False, 'msg': '电影已经存在!!' } else: send_dic = {'flag': True, 'msg': '可以继续上传'} common.send_data(send_dic, conn) @common.login_auth def upload_movie_interface(back_dic, conn): # 保证电影的名字唯一性 movie_name = common.get_session() + back_dic.get('movie_name') movie_path = os.path.join(setting.MOVIE_DIR, movie_name) movie_size = back_dic.get('movie_size') recv_data = 0 with open(movie_path, 'wb') as f: while recv_data < movie_size: data = conn.recv(1024) f.write(data) recv_data += len(data) movie_obj = Movie( movie_name=movie_name, movie_size=movie_size, movie_md5=back_dic.get('movie_md5'), is_free=back_dic.get('is_free'), is_delete=0, upload_time=str(datetime.datetime.now()), user_id=back_dic.get('user_id')) movie_obj.insert_data() send_dic = { 'flag': True, 'msg': '电影上传成功' } common.send_data(send_dic, conn) @common.login_auth def delete_movie_interface(back_dic, conn): movie_id = back_dic.get('movie_id') movie_obj = Movie.select_data(m_id=movie_id)[0] movie_obj.is_delete = 1 movie_obj.update_data() send_dic = { 'flag': True, 'msg': '电影删除成功' } common.send_data(send_dic, conn) @common.login_auth def send_notice_interface(back_dic, conn): notice_obj = Notice( title=back_dic.get('title'), content=back_dic.get('content'), create_time=str(datetime.datetime.now()), user_id=back_dic.get('user_id')) notice_obj.insert_data() send_dic = { 'msg': '公告发布成功' } common.send_data(send_dic, conn)admin_interface.py
from lib import common from db.models import Movie, DownLoadRecord from db.models import User from db import user_data import datetime from threading import Lock from conf import setting import os mutex = Lock() # 未删除电影接口 @common.login_auth def get_movie_list_interface(back_dic, conn): movie_obj_list = Movie.select_data() if movie_obj_list: movie_list = [] for movie_obj in movie_obj_list: if not movie_obj.is_delete: if back_dic.get('movie_type') == 'all': movie_list.append([movie_obj.movie_name, movie_obj.m_id, '免费电影' if movie_obj.is_free else '收费电影']) elif back_dic.get('movie_type') == 'free': if movie_obj.is_free: movie_list.append([movie_obj.movie_name, movie_obj.m_id, '免费电影']) else: if not movie_obj.is_free: movie_list.append([movie_obj.movie_name, movie_obj.m_id, '收费电影']) send_dic = { 'flag': True, 'movie_list': movie_list } else: send_dic = { 'flag': False, 'msg': '服务端没有电影' } common.send_data(send_dic, conn) def register_interface(back_dic, conn): username = back_dic.get('username') user_obj_list = User.select_data(user_name=username) if user_obj_list: send_dic = { 'flag': False, 'msg': '用户已存在!' } else: pwd = common.get_md5(back_dic.get('password')) user_obj = User( user_name=username, user_pwd=pwd, user_type=back_dic.get('user_type'), register_time=str(datetime.datetime.now()) ) user_obj.insert_data() send_dic = { 'flag': True, 'msg': f'用户{username}注册成功' } common.send_data(send_dic, conn) def login_interface(back_dic, conn): user_obj = User.select_data(user_name=back_dic.get('username'))[0] if not user_obj: send_dic = {'flag': False, 'msg': '用户不存在'} else: if user_obj.user_pwd == common.get_md5(back_dic.get('password')): addr = back_dic.get('addr') session = common.get_session() mutex.acquire() user_data.user_online[addr] = [session, user_obj.user_id] mutex.release() send_dic = { 'flag': True, 'msg': '登录成功!', 'session': session } if user_obj.is_vip: send_dic['is_vip'] = user_obj.is_vip else: send_dic = {'flag': False, 'msg': '密码错误!!!'} common.send_data(send_dic, conn) @common.login_auth def download_movie_interface(back_dic, conn): user_id = back_dic.get('user_id') user_obj = User.select_data(user_id=user_id)[0] movie_name = back_dic.get('movie_name') movie_path = os.path.join(setting.MOVIE_DIR, movie_name) send_dic = { 'movie_size': os.path.getsize(movie_path), 'wait_time': 0 } if not user_obj.is_vip: send_dic['wait_time'] = 10 common.send_data(send_dic, conn, file=movie_path) download_obj = DownLoadRecord( movie_id=back_dic.get('movie_id'), user_id=user_id, download_time=str(datetime.datetime.now()) ) download_obj.insert_data()common_interface.py
from db.models import User, DownLoadRecord, Movie, Notice from lib import common @common.login_auth def buy_vip_interface(back_dic, conn): user_id = back_dic.get('user_id') user_obj = User.select_data(user_id=user_id)[0] user_obj.is_vip = 1 user_obj.update_data() send_dic = {'msg': '充值会员成功,请重新登录'} common.send_data(send_dic, conn) @common.login_auth def check_download_record_interface(back_dic, conn): user_id = back_dic.get('user_id') down_load_obj_list = DownLoadRecord.select_data(user_id=user_id) if not down_load_obj_list: send_dic = { 'flag': False, 'msg': '没有下载记录' } else: download_list = [] for download_obj in down_load_obj_list: movie_id = download_obj.movie_id movie_obj = Movie.select_data(m_id=movie_id)[0] download_list.append([movie_obj.movie_name, download_obj.download_time]) send_dic = { 'flag': True, 'download_movie_list': download_list } common.send_data(send_dic, conn) @common.login_auth def check_notice_interface(back_dic, conn): notice_obj_list = Notice.select_data() if not notice_obj_list: send_dic = { 'flag': False, 'msg': '暂无公告' } common.send_data(send_dic, conn) else: notice_list = [] for notice_obj in notice_obj_list: notice_list.append([notice_obj.title, notice_obj.content, notice_obj.create_time]) send_dic = { 'flag': True, 'notice_list': notice_list } common.send_data(send_dic, conn)user_interface.py
lib文件夹
import struct import json import hashlib import uuid from threading import Lock from db.user_data import user_online mutex = Lock() def send_data(back_dic, conn, file=None): bytes_data = json.dumps(back_dic).encode('utf-8') header = struct.pack('i', len(bytes_data)) conn.send(header) conn.send(bytes_data) if file: with open(file, 'rb') as f: for i in f: conn.send(i) def get_md5(pwd): md5_obj = hashlib.md5() md5_obj.update(pwd.encode('utf-8')) salt = '天王盖地虎' md5_obj.update(salt.encode('utf-8')) return md5_obj.hexdigest() def get_session(): uuid_str = str(uuid.uuid4()) session_val = get_md5(uuid_str) return session_val def login_auth(func): def inner(*args, **kwargs): # args = (back_dic, conn) client_session = args[0].get('cookies') addr = args[0].get('addr') mutex.acquire() # 'addr': [session, user_obj.user_id] session_id_list = user_online.get(addr) mutex.release() if session_id_list: if client_session == session_id_list[0]: args[0]['user_id'] = session_id_list[1] res = func(*args, **kwargs) return res else: send_dic = {'flag': False, 'msg': '携带session值错误'} send_data(send_dic, args[1]) else: send_dic = {'flag': False, 'msg': '用户未登录,没有执行权限'} send_data(send_dic, args[1]) return innercommon.py
tcp_server文件夹
from interface import admin_interface from interface import common_interface from interface import user_interface import socket import struct import json from concurrent.futures import ThreadPoolExecutor from threading import Lock from db import user_data mutex = Lock() pool = ThreadPoolExecutor(50) func_dic = {'register': common_interface.register_interface, 'login': common_interface.login_interface, 'check_movie': admin_interface.check_movie_interface, 'upload_movie': admin_interface.upload_movie_interface, 'get_movie_list': common_interface.get_movie_list_interface, 'delete_movie': admin_interface.delete_movie_interface, 'send_notice': admin_interface.send_notice_interface, 'buy_vip': user_interface.buy_vip_interface, 'download_movie': common_interface.download_movie_interface, 'check_download_record': user_interface.check_download_record_interface, 'check_notice': user_interface.check_notice_interface} def working(conn, addr): while True: try: headers = conn.recv(4) bytes_len = struct.unpack('i', headers)[0] json_data = conn.recv(bytes_len).decode('utf-8') back_dic = json.loads(json_data) # 保证每个客户端过来都是唯一的,将addr添加到客户端发过来的字典中 back_dic['addr'] = str(addr) func_type = back_dic.get('func_type') if func_type in func_dic: func_dic[func_type](back_dic, conn) except Exception as e: print(e) # 清除当前客户端存放在服务端的session值 mutex.acquire() user_data.user_online.pop(str(addr)) mutex.release() break conn.close() def run(): server = socket.socket() server.bind(('127.0.0.1', 9876)) server.listen(50) while True: conn, addr = server.accept() print(addr) # 异步提交任务 pool.submit(working, conn, addr)socket_server.py