TCP聊天+传输文件服务器服务器套接字v2.7

刚创建服务器的时候为了后期便于管理, 主要也是MySQL对我不适合, 跨平台使用, 一打包还有得装, 所以直接自己做了个
这是我写的服务器的数据库代码, 可见一看就能看出来, 数据库只存在于单个文件data.json中, I/O十分频繁, 用户信息文件存于运行内存中, 在小数据的情况下速度快, 但到数据存于一定程度, 性能断崖式下跌, 且 在taskmgr(任务管理器) 中内存一举超过了 1.78G的pycharm, 成为第一.

提升性能的方法:

  1. 变量使用 set

    可变,无序的,不重复的元素集合 (不可出现 listsetbytearray 等无__hash__(self)哈希值的类)

    – set 的 时间复杂度为 O1, list 的 时间复杂度为 On.

    – set内部存储元素必是可hash的,而且还是不可重复的.
    当每一个set中的元素都有一个独立hash的编码,虽然外面看元素是乱序的,但是内部其实是hash编码的排序,当运行时是通过编码查询,所以会如此之快(warning:是有可能出现hash冲突,但是极少)

  2. 避免单文件频繁调用I/O

  3. 用户建立文件夹, 一个文件夹对应一个用户的md5值(sha256的都行), 这是为了创建文件夹时候避免非法字符的出现.

  4. 类似于文件传输服务器, 传来的文件最好解压分割切片

  5. 只将用户名存于运行内存中, 节省空间, 一般数据库也不会大于几TB, 把密码, 注册时间这些杂七杂八的东西放在文件夹下面

行了, 后面的直接不用看了, 按左上角的退出键退出吧

这是data.py代码(全部data.py 在gitcode - https://gitcode.net/m0_60394896/python/-/blob/05267ff4f3c2267954dc87e505d034229eaa0f98/server/data.py)

from json import load, dump
from os import path, mkdir
from hashlib import md5
from time import timedef encode(data: str):m = md5()m.update(data.encode('utf8'))return m.hexdigest()file = '.\clients\data.json'
folder = '.\clients'
if not path.exists(folder):mkdir(folder)class data:def __init__(self):if path.exists(file):with open(file, 'r') as f:self.data = load(f)else:self.data = {}def __get__(self, username, default=None) -> tuple:return self.data.get(username, default)def __in__(self, username) -> bool:return username in self.data.keys()def __write__(self) -> None:with open(file, 'w') as f:dump(self.data, f, indent=4)def __register__(self, username, password, time: (int, float) = time()) -> None:...self.__write__()def __login__(self, username, password) -> bool:return self.data[username][0] == encode(password)def get_time(self, username):return self.data[username][1]def handler(self, type: int, username: str, password: str):...

文章目录

  • 测试
  • 提升性能

所有版本记录:
v1.0 : TCP聊天服务器套接字|PyQt5+socket(TCP端口映射+端口放行)+logging+Thread(含日志,html)+anaconda打包32位exe(3.4万字)|python高阶
v1.1 : python TCP套接字服务器v1.1-新增服务端命令功能及修改bug(socket+PyQt5)
v1.2 : python TCP服务器v1.2 - 服务端新增用户登录注册(json, md5加密)
v1.3 : python TCP服务器v1.3 - 服务器抗压测试及关闭套接字处理
v1.4 : python TCP服务器v1.4 - 客户端连接服务器异常(异常情况分类)处理
v1.5 : PyQt5可编辑下拉框(comboBox):editable - python TCP服务器v1.5 - 客户端连接界面增加自定义参数(设置超时, 连接地址可选)
v1.6 : Python TCP服务器v1.6 - multiprocessing多进程及Ctrl-c(SIGINT)退出
v1.7 : Python TCP服务器v1.7 - PyQt5 server服务端来临
v1.8 : python TCP服务器v1.8 - PyQt5登录界面美化+淡入淡出
v1.9 : socketTCP协程文件+信息传递 - TCP聊天文件服务器v1.9 - 划时代的版本更新(4.6万字)
v2.0 : TCP聊天文件服务器v2.0 - 重大bug修复+PyQt5文件传输可视化
v2.1 : TCP聊天文件服务器v2.1 - 服务端线程管理(threading.enumerate)
v2.2 : TCP聊天文件服务器v2.2 - 服务端客户端套接字解决分包/粘包问题 - SocketQueue继承以及减少冗余
v2.3 : gzip的使用 - TCP聊天文件服务器v2.3 - 文件传输建立缓存制度和.gz的解压缩/压缩解决运行内存过大
v2.4 : 网络传输测速 - TCP聊天+传输文件服务器服务器套接字v2.4 - socket协程文件传送测速
v2.5 : TCP聊天+传输文件服务器服务器套接字v2.5 - socket测速规范已经gzip的弃用
v2.6 : TCP聊天+传输文件服务器服务器套接字v2.6 - 登录注册界面更新 - loading界面应用

测试

增加数据库 用户登录注册的时候还是在 v1.2,

import itertools
from threading import Threaddef threading(Daemon, name=None, **kwargs):thread = Thread(**kwargs)thread.setDaemon(Daemon)if name:thread.setName(name)thread.start()return threaddata = data()
print(data.handler(0, "tqm", "asdf"))a = 0for u in itertools.product("qwertyuiop[]asdfghjkl;'\\zxcvbnm,./`12345678900-", repeat=6):p = "阿斯蒂芬asdf"a += 1if a % 400 == 0:data.handler(1, "".join(u), "".join(p), _show_detail=True)print(a)else:data.handler(1, "".join(u), "".join(p), _show_detail=False)if a > 1000000:sys.exit(a)
2022-06-20 12:49:00,951 - data.py[line:51] - INFO: Execute the function User handle, timeit 0.000
(False, '用户不存在!', '')
2022-06-20 12:49:01,743 - data.py[line:51] - INFO:
Execute the function User handle, timeit 0.002
2022-06-20 19:11:20,572 - data.py[line:145] - INFO: size: 799.9Mb(8319541 bytes)
... ...
2022-06-20 19:14:37,143 - data.py[line:51] - INFO: Execute the function User handle, timeit 2.496
2022-06-20 19:14:37,144 - data.py[line:145] - INFO: size: 800.0Mb(8354830 bytes)
2022-06-20 19:17:45,165 - data.py[line:51] - INFO: Execute the function User handle, timeit 2.531
2022-06-20 19:17:45,165 - data.py[line:145] - INFO: size: 800.0Mb(8385887 bytes)

在运行了长达3, 8400次迭代后, 连一个注册用户都已经超过了秒的单位.

提升性能

set list
add append
from json import load, dump, decoder
from os import path, mkdir, listdir
from hashlib import md5
from time import time
import logginglogging.basicConfig(level=logging.DEBUG,format="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
logger = logging.getLogger(__name__)def _mkdir(_folder):try:if not path.exists(_folder):mkdir(_folder)return Trueexcept NotImplementedError:logger.exception("")return Falsedef encode(_data: str):m = md5()m.update(_data.encode('utf8'))return m.hexdigest()def timeit(objname: str, ign=True):def setup_function(func_name):def _exec_function(*args, _show_detail=True, **kwargs):startime = time()_resp = func_name(*args, **kwargs)if _show_detail:logger.info("Execute the function %s%s, timeit %0.3f" % (objname.title(), "" if ign else f" (at {str(func_name)})", time() - startime))return _respreturn _exec_functionreturn setup_functionfolder = r'.\clients'
_mkdir(folder)data = set()
if path.isdir(folder):try:data = set(listdir(folder))except decoder.JSONDecodeError:passdef __in__(username) -> bool:return username in datadef register(username, password, register_time: (int, float) = time()) -> None:global datadata.add(username)user_path = path.join(folder, encode(username))print(user_path, _mkdir(user_path))_mkdir(user_path)with open(path.join(user_path, "user.json"), "w") as f:dump({"username": username, "password": password, "register_time": int(register_time)}, f, indent=4)def login(username, password) -> bool:with open(path.join(path.join(folder, encode(username)), "user.json"), "r") as f:_data = load(f)return _data.get("username", "") == username and _data.get("password", "") == passworddef get_time(username):with open(path.join(path.join(folder, encode(username)), "user.json"), "r") as f:return load(f).get("register_time")@timeit("User Handle")
def handler(_type: int, username: str, password: str):username = username.strip()if not username:return False, "未填写用户名!", ""password = password.strip()if not password:return False, "未填写密码!", ""if not 2 <= len(username) <= 12:return False, "用户名需在2~12位之间!", ""if not 4 <= len(password) <= 10:return False, "密码需在4~10位之间!", ""if _type == 0:  # loginif not __in__(username):return False, "用户不存在!", ""if not login(username, password):return False, "用户名 / 密码错误!", ""return True, "欢迎回来, " + username, usernameelif _type == 1:  # registerif __in__(username):return False, "已存在用户!", ""register(username, password)return True, "初来乍到, " + username, username

就是将每个用户的用户名的md5值存于文件夹, user.json放信息

python 数据库性能提升 - TCP聊天+传输文件服务器服务器套接字v2.7相关推荐

  1. TCP聊天+传输文件服务器服务器套接字v2.6 - 登录注册界面更新 - loading界面应用

    TCP聊天+传输文件服务器服务器套接字v2.6 更改的地方: 主要是客户端界面更改 注册, 登录界面 (都知道啊, v1.8的改进后输入用户名, 到了主界面的时候才能输入密码, 但现在是直接输入用户名 ...

  2. MFC基于TCP协议的CSocket类套接字服务器端代码示范

    MFC基于TCP协议的CSocket类套接字服务器端代码示范 https://blog.csdn.net/txwtech/article/details/93417667 转载于:https://ww ...

  3. 前端学习(1856)vue之电商管理系统电商系统之安装mysql出现mysql报错:Can’t start server: Bind on TCP/IP port: 通常每个套接字地址(协议/网络地址

    2020-07-26T11:44:29.778919Z 0 [ERROR] [MY-010262] [Server] Can't start server: Bind on TCP/IP port: ...

  4. Python网络编程——使用TCP方式传输文件

    TCP文件下载器 客户端 需求:输入要下载的文件名,从服务器端将文件拷贝到本地 步骤: 1.创建TCP套接字,绑定端口 2.连接服务端 3.输入要下载的文件名 4.将文件名编码,并发送到服务端 5.接 ...

  5. 微服务架构 性能提升_如何通过无服务器架构提高性能

    微服务架构 性能提升 by Domenico Angilletta 通过多梅尼科·安吉列塔(Domenico Angilletta) 如何通过无服务器架构提高性能 (How to boost your ...

  6. python中http协议编程_python网络编程、套接字、HTTP协议

    网络编程 网络目的 : 数据的传输 网络数据传输是一个复杂的过程 OSI 七层模型 --> 网络通信标准化流程 应用层 : 提供用户服务,具体内容由特定程序规定 表示层 : 数据的压缩优化 会话 ...

  7. python socket清空接收缓冲区_Python网络编程——修改套接字发送和接收的缓冲区大小...

    很多情况下,默认的套接字缓冲区大小可能不够用.此时,可以将默认的套接字缓冲区大小改成一个更合适的值. 1. 代码 # ! /usr/bin/env python # -*- coding: utf-8 ...

  8. 网络协议OSI、TCP/IP协议、Socket套接字和第三方AsyncSock的使用等解析

    一.网络协议定义 1.OSI参考模型:全称(Open System Interconnection), 开放式系统互联参考模型.是一个逻辑上的定义,一个规范,它把网络协议从逻辑上分为七层,只要目的是为 ...

  9. 网络七层协议 五层模型 TCP连接 HTTP连接 socket套接字

    socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程 ...

最新文章

  1. appium+python自动化45-夜神模拟器连不上(adb server version (36) doesn't match this client (39); killing...)...
  2. 【Linux】一步一步学Linux——lastb命令(99)
  3. hive与hbase的以及mongodb和cassandra区别整理
  4. php html标签闭合,php截取字符串,完美html自动闭合
  5. C# 离线使用nuget
  6. mysql mos login_MySQL 中常用的函数
  7. Django---Cookie Session 分页
  8. access游戏库不显示 ea_EAAccess服务Steam平台售价一览 EAAccess服务常见问题解答
  9. 近 45 亿元拿下开源服务器 Nginx,F5 买断应用交付未来?
  10. 抽象类的成员特点 学习笔记
  11. Typora下载链接
  12. 我国大部地区遭罕见寒潮 23省区应急响应
  13. Gradle使用Junit5进行test
  14. python知道章节答案_智慧树知道Python数据分析与数据可视化答案,章节期末教程考试网课答案...
  15. Java基础之《netty(28)—TCP粘包拆包原理》
  16. Cannot deserialize instance of `com.xxx.project.biz.domain.xxx` out of START_ARRAY token;
  17. 智能分析网关微信端告警消息推送的开发流程
  18. 恢复误删excel工作薄中的表格
  19. Spring IoC 和 AOP
  20. R语言 绘图 (ggplot2)

热门文章

  1. MIUI系统降级刷机
  2. vue跟app交互,app调用vue方法报defined
  3. 如何将多个PDF的首页整合成一个单独的PDF
  4. 干货!公平意识在在线元学习的研究
  5. layui时间选择器选择周和季度
  6. signature=6f1ae6ad5c67016da86cc9325f33f066,中国石油自主聚丙烯熔喷专用料开发成功
  7. 使用Qiskit学习量子计算_3基础语法(下)
  8. 论文里的讨论怎么写?
  9. 【图片】机器学习--名画风格 neural-style
  10. 【java程序运行机制】