import os import re import socket import threading import msgpack DATA_NODE_DEFAULT_PORT = 7777 DATA_HEAD = b"\xDD\xAA\xAA" DEFAULT_IP_SEGMENT = r"192.168.137.(?!255)[0-9]{1,3}" # 获得自身的ip地址 def get_self_ip_address(): ip_list = get_machine_ip_address() return ip_list[0] # 获得同个网段下的设备 def get_machine_ip_address(): echo = os.popen("arp -a").read() return re.findall(DEFAULT_IP_SEGMENT, echo) def send_2(domain, data, port=DATA_NODE_DEFAULT_PORT): data_bytes = msgpack.dumps(data) data_len = len(data_bytes) len_bytes = int.to_bytes(data_len, 3, byteorder="big") data_body = DATA_HEAD + len_bytes + data_bytes try: client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # client.bind((get_self_ip_address(), 0)) client.bind((DataNode.SELF_IP, 0)) client.settimeout(1) client.connect((domain, port)) client.send(data_body) client.close() return True except Exception as e: # print(e) return False class DataNode(threading.Thread): SELF_IP = "0.0.0.0" def __init__(self, domain="0.0.0.0", port=DATA_NODE_DEFAULT_PORT, report=False) -> None: super().__init__(daemon=True) self.report = report self.domain = domain self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tcp_server.bind((self.domain, port)) self.tcp_server.listen(1024) self.tcp_server.settimeout(1) self.data = b"" self.package = [] self.__running = threading.Event() # 用于停止线程的标识 self.__running.set() # 将running设置为True self.__had_data = threading.Event() self.__had_data.clear() def get_data(self): if self.package: return self.package.pop(0) def clear_data(self): self.data = b"" self.package.clear() def _thread_data_processing(self): while self.__running.is_set(): self.__had_data.wait() while self.data: head = re.search(DATA_HEAD + b"(.|\n|\r){3}", self.data) if not head: continue data_start = head.end() data_len_mes = head.group()[3:6] high_byte = data_len_mes[0] middle_byte = data_len_mes[1] low_byte = data_len_mes[2] data_len = high_byte * 256 * 256 + middle_byte * 256 + low_byte data_end = data_start + data_len data_bytes = self.data[data_start: data_end:] # 解析数据 try: data = msgpack.loads(data_bytes) except: continue self.package.append(data) # 更新数据 self.data = self.data[data_end::] self.__had_data.clear() def start(self) -> None: super().start() threading.Thread(target=self._thread_data_processing, daemon=True).start() def run(self) -> None: while self.__running.is_set(): # 等待客户端连接 connected_addr = None try: conn, connected_addr = self.tcp_server.accept() conn: socket.socket conn.settimeout(1) if self.report: print("[Data Node]{} connected!".format(connected_addr)) while True: try: data = conn.recv(8192) if data: # print("receive", data) self.data += data self.__had_data.set() else: if self.report: print("[Data Node]{} disconnected!".format(connected_addr)) break except socket.timeout: continue except: if self.report: print("[Data Node]{} disconnected!".format(connected_addr)) break except socket.timeout: if connected_addr: if self.report: print("[Data Node]{} disconnected!".format(connected_addr)) except ConnectionResetError: if connected_addr: if self.report: print("[Data Node]{} disconnected!".format(connected_addr)) except Exception as e: if connected_addr: if self.report: print("[Data Node]{} disconnected!".format(connected_addr)) self.tcp_server.close() def stop(self): try: self.__running.clear() self.tcp_server.close() except: return