包含服务端多线程处理客户端,客户端长连接发送消息给服务端,以及客户端断线重连策略。
设计思路:
服务端通过在初始化方法中传入 handle_fun
,handle_fun参数为:处理客端方法的方法名,并通过线程的方式来处理每一个客户端连接。
完整代码:
import socket import threading import time class SocketServer: """ SOCKET 服务端 """ def __init__(self, host, port, handle_fun): """ 初始化 socket 服务端 :param host: socket绑定的ip :param port: socket绑定的端口 :param handle_fun: 处理客户端方法的方法名 """ self.host = host self.port = port self.handle_fun = handle_fun def start_server(self): """ 启动 TCP_SERVER 端服务 :return: """ try: # 1. 初始化服务端socket self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 防止socket server重启后端口被占用(socket.error: [Errno 98] Address already in use) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 2. bind:将套接字与本地主机和端口绑定 # host = socket.gethostname() # 获取本地主机名称 self.socket.bind((self.host, self.port)) # 3. listen:设置监听最大连接数 self.socket.listen(10) except socket.error as msg: print(msg) # 获取本地服务器的连接信息 myaddr = self.socket.getsockname() print("启动——Socket服务,服务端地址:%s" % str(myaddr)) while True: # 4. accept:获取一个客户端连接 clientsocket, addr = self.socket.accept() print("连接地址:%s" % str(addr)) try: # 5. 为每一个请求开启一个处理线程 threading.Thread(target=self.handle_fun, args=(clientsocket, addr,)).start() pass except Exception as identifier: print(identifier) pass # 7. close self.socket.close()
设计思路:
客户端设计思路主要分为两块:与服务端建立连接,其次是发送消息
建立连接:
正常与服务端建立连接:self.socket.connect((self.host, self.port))
当连接异常时:通过异常捕获的方式,在异常处理中,进行不断重新建立连接操作,直到连接成功为主。
发送消息:
设计成简单的长连接操作:
当建立连接之后,一直进行发送消息,而不是短连接,每发一条消息之前进行一次连接操作。
但是会存在另外一个问题,python无法进行socket的状态判断,说白了就是没办法判断是否连接还正常。
所以我在发送消息的操作中,通过在异常捕获的函数片段中,增加断线重连机制。
完整代码:
class SocketClient: """ socket客户端 """ def __init__(self, host, port, timeout=10, encoding='utf-8'): self.host = host self.port = port self.timeout = timeout self._encoding = encoding def create_connect(self): """ 建立连接 :return: """ try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务端 self.socket.connect((self.host, self.port)) # 设置超时响应 self.socket.settimeout(self.timeout) except socket.error as e: print("TCP服务器连接异常,尝试重新连接 (5s) ...!, %s", e) self.socket.close() time.sleep(5) # 断开连接后,每 5s 重新连接一次 self.create_connect() def send_msg(self, msg): """ 客户端发送消息 增加客户端断线重连机制 :param msg: :return: """ try: self.socket.send(msg.encode(self._encoding)) except socket.error as e: print("TCP服务器连接异常,尝试重新连接 (5s) ...!, %s", e) # 重新建立连接 self.create_connect()
tcp_python工具类
包含 工具类,以及对应的 服务端和客户端的测试代码