TCP聊天+传输文件服务器服务器套接字v2.3
所有版本记录:
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继承以及减少冗余
传几个大文件就直接飙升几个G…
为了解决这个问题,可以一点一点读取压缩 发送, 一点一点的接收, 然后直接存入缓存文件中.
from gzip import compress, decompress
class message_handle:
codec = "utf8"
def __init__(self, server: Server):
if not os.path.isdir(save_path):
os.makedirs(save_path)
self.Sender = send_files(self.codec, )
self.Receiver = recv_files(self.codec, save_path)
self.files_record = {}
self.server = server
@to_logging
def handle(self, data, client: Client):
_res = get_eval(data, tuple())
if len(_res) == 2:
type, arguments = _res
if type == new_file:
index, name, total, size = arguments
if not client.username in self.files_record:
if index == 0:
self.files_record[client.username] = [len(self.Receiver.recvs), ]
else:
self.files_record[client.username].append(len(self.Receiver.recvs))
self.Receiver.new_files(len(self.Receiver.recvs), name, total, size)
elif type == update_file:
index, progress, data = arguments
if client.username in self.files_record:
if not len(self.files_record[client.username]) >= index + 1:
index = len(self.files_record[client.username]) - 1
_res = self.Receiver.apply(self.files_record[client.username][index], progress, data)
if _res:
INDEX, NAME = _res
self.server.UserMessage(client.addr, client.username, f'<a href="{INDEX}">{NAME}</a>')
elif type == request_file:
path = self.Receiver.recvs[arguments].savepath()
if path:
self.Sender.localfile(path, client.send) # 如若无, 报错False
elif type == normal_text:
return arguments
def send(self, sendpath, conn):
return self.Sender.localfile(sendpath, conn)
def get_index(self, index):
if index + 1 <= len(self.Receiver.recvs):
return self.Receiver.recvs[index]
class message_handle:
codec = "utf8"
def __init__(self, func: callable = lambda _: True):
self.Sender = send_files(self.codec, )
self.Receiver = recv_files(self.codec, save_path)
self.func = func
self.Progress = []
def handle(self, data):
_res = get_eval(data, (None,))
if len(_res) == 2:
type, arguments = _res
if type == new_file:
self.Receiver.new_files(*arguments)
elif type == update_file:
self.Receiver.update(*arguments)
elif type == request_file:
path = self.Receiver.get_index(arguments).savepath()
if path:
self.Sender.localfile(path, self.func) # 如若无, 报错False
elif type == normal_text:
return arguments
def send(self, sendpath):
return self.Sender.localfile(sendpath, self.func)
def send_text(self, mes: str):
return self.func(repr((normal_text, mes)).encode(self.codec))
def request_file(self, name):
index = get_eval(name, 0)
if self.in_list(index):
self.get_index(index).start()
return
self.func(repr((request_file, index)).encode(self.codec))
def get_index(self, index) -> RECV:
return self.Receiver.get_index(index)
def in_list(self, index):
return self.Receiver.in_list(index)