1 Star 0 Fork 3

JOHNSON / multithreaded-socket

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
server.py 6.02 KB
一键复制 编辑 原始数据 按行查看 历史
JOHNSON 提交于 2021-07-27 12:17 . 仿 HTTP 协议传输
import socket
import threading
import buff
from utils import logging
from handler import BaseHandler
from buff import Buff
from protocol import Protocol, TEXT_MESSAGE, JSON_MESSAGE, FILE_MESSAGE
class TCPServer(object):
def __init__(self, host: str, port: int, handler_cls):
self.server_address = (host, port)
self.handler_cls: BaseHandler = handler_cls
# 初始化套接字对象
self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__socket.bind(self.server_address)
self.__socket.listen(5)
# 是否关闭状态
self.__is_shutdown: bool = True
# 客户端列表, 存在字典里 key 是客户端地址, value 是对应的客户端 handler 实例
self.client_list: dict = {}
# 客户端json列表, 给前端用的 {'ip:port': {information}}
# self.client_list_obj: dict = {}
def run_server(self):
self.__is_shutdown = False
threading.Thread(target=self.__run).start()
def __run(self):
logging.info("服务器运行在 {}:{}".format(self.server_address[0], self.server_address[1]))
while not self.__is_shutdown:
try:
client, remote_address = self.__socket.accept()
except Exception as e:
break
threading.Thread(target=self.on_connection, args=(client, remote_address)).start()
def on_connection(self, client: socket.socket, remote_address: tuple):
handler: BaseHandler = self.handler_cls(client, remote_address, self)
self.client_list["%s:%d" % (remote_address[0], remote_address[1])] = handler
self.wait_recv(handler)
def wait_recv(self, handler: BaseHandler):
while handler.is_connection:
try:
request: Protocol = Protocol.handler(buff=handler.buff)
if request is None:
"""
数据包结构错误
"""
handler.on_connect_err('ProtocolError', descriotion="数据包结构错误, 已断开链接")
break
if request.body == b'':
handler.on_connect_err('ConnectionResetError', descriotion="远程主机主动断开连接")
break
except ConnectionResetError:
"""
异常处理, ConnectionResetError 远程主机主动断开连接
该异常是对方主动与我方断开连接,
"""
handler.on_connect_err('ConnectionResetError', descriotion="远程主机主动断开连接")
break
except ConnectionAbortedError:
"""
异常处理, ConnectionAbortedError 你的主机中软件终止了一个已建立的连接
该异常是我方主动与对方断开连接,
"""
handler.on_connect_err('ConnectionAbortedError', descriotion="你的主机中软件终止了一个已建立的连接")
break
except Exception:
"""
异常处理, 奇奇怪怪的异常处理,
该异常处理其他异常
"""
handler.on_connect_err('OtherError', descriotion="异常处理, 奇奇怪怪的异常处理")
return None, True
handler.on_message(request)
return False
def send(self, protocol: Protocol, target=None):
"""
发送消息
:param protocol:
:param target:
:return:
"""
# 先判断目标是不是空, 是空为广播
if target is None:
for key in list(self.client_list):
client: BaseHandler = self.client_list[key]
try:
client.send(protocol)
except Exception:
client.on_connect_err('ConnectionSendError', descriotion="发送信息失败, 连接可能已经断开")
del self.client_list[key]
# del self.client_list_obj[key]
# 指定目标就发送给指定客户端
else:
client = self.client_list[target]
try:
client.send(protocol)
except Exception:
client.on_connect_err('ConnectionSendError', descriotion="发送信息失败, 连接可能已经断开")
del self.client_list[target]
# del self.client_list_obj[target]
def node_disconnection(self, remote_address):
host = f"{remote_address[0]}:{remote_address[1]}"
del self.client_list[host]
# del self.client_list_obj[host]
@property
def is_shutdown(self):
return self.__is_shutdown
def close(self):
# is Shutdown
self.__is_shutdown = True
# 关闭套接字连接
self.__socket.close()
# 清空列表
self.client_list.clear()
# self.client_list_obj.clear()
logging.info("服务器已关闭 {}:{}".format(self.server_address[0], self.server_address[1]))
@property
def is_run(self):
return not self.__is_shutdown
class SimpleHandler(BaseHandler):
def before_request_middleware(self, request: Protocol) -> bool:
if request.header.get("test") and request.header.get("test") == "Test Header":
return True
return False
def text_handler(self, request: Protocol):
print("type: ", request.type)
print("version: ", request.version)
print("header: ", request.header)
print(request.body.decode("utf-8"))
def json_handler(self, request: Protocol):
pass
def file_handler(self, request: Protocol):
pass
if __name__ == '__main__':
server = TCPServer("127.0.0.1", 8848, SimpleHandler)
server.run_server()
while server.is_run:
data = input()
if data == "exit":
server.node_disconnection()
break
p = Protocol(TEXT_MESSAGE, data)
p.set_header("test", "Test Header")
server.send(p)
Python
1
https://gitee.com/J0hNs0N/multithreaded-socket.git
git@gitee.com:J0hNs0N/multithreaded-socket.git
J0hNs0N
multithreaded-socket
multithreaded-socket
master

搜索帮助