diff --git a/mainwindow.py b/mainwindow.py index 36e1ded..58a298b 100644 --- a/mainwindow.py +++ b/mainwindow.py @@ -8,7 +8,8 @@ from scipy.fft import fft, fftfreq import matplotlib.pyplot as plt from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QFrame, QGridLayout, QStatusBar, QSizePolicy, QFileDialog -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, QTimer, pyqtSlot, QByteArray +from PyQt5.QtNetwork import QTcpSocket, QAbstractSocket import matplotlib import struct import time @@ -80,6 +81,18 @@ class SocketClientApp(QMainWindow): self.setWindowTitle("Socket Client & Data Plotter") self.setGeometry(100, 100, 700, 600) # 设置初始尺寸 + self.buffer = QByteArray() + self.reconnect_timer = QTimer(self) + self.reconnect_timer.timeout.connect(self.attempt_reconnect) + self.reconnect_interval = 5000 + self.max_reconnect_attempts = 5 + self.current_reconnect_attempts = 0 + + self.socket = QTcpSocket(self) + self.socket.readyRead.connect(self.on_ready_read) + self.socket.disconnected.connect(self.on_socket_disconnected) + self.socket.errorOccurred.connect(self.on_socket_error) + # 组件初始化 self.ip_label = QLabel("IP 地址:") self.port_label = QLabel("端口号:") @@ -209,30 +222,37 @@ class SocketClientApp(QMainWindow): crc += byte return crc & 0xFF # 只保留最低字节 def connect_to_server(self): - """ 连接到服务器 """ - self.ip = self.ip_input.text() - self.port = self.port_input.text() + ip = self.ip_input.text() + port = int(self.port_input.text()) + self.socket.abort() + self.socket.connectToHost(ip, port) - if not self.ip or not self.port: - self.status_bar.showMessage("状态: 请输入有效的 IP 和端口号") + def on_socket_disconnected(self): + self.status_bar.showMessage("状态: 连接断开,正在重连...") + self.get_data_button.setEnabled(False) + self.reconnect_timer.start(self.reconnect_interval) + def on_socket_error(self, error): + self.status_bar.showMessage(f"状态: 错误 - {self.socket.errorString()}") + + def attempt_reconnect(self): + if self.current_reconnect_attempts >= self.max_reconnect_attempts: + self.reconnect_timer.stop() + self.status_bar.showMessage("状态: 重连失败,请检查网络") return + self.current_reconnect_attempts += 1 + self.connect_to_server() - try: - self.port = int(self.port) - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.settimeout(2) - # 设置 keep-alive 选项 - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - self.socket.connect((self.ip, self.port)) + def on_ready_read(self): + self.buffer += self.socket.readAll() - self.get_data_button.setEnabled(True) # 连接成功,启用获取数据按钮 - self.upgrade_button.setEnabled(True) - self.upgrade_button_test.setEnabled(True) - self.status_bar.showMessage(f"状态: 连接成功! 服务器 {self.ip}:{self.port}") - - except Exception as e: - self.status_bar.showMessage(f"状态: 连接失败 - {str(e)}") + def receive_data(self, length: int): + while len(self.buffer) < length: + if not self.socket.waitForReadyRead(1000): + raise ConnectionError("等待数据超时") + data = self.buffer[:length] + self.buffer = self.buffer[length:] + return bytes(data) def parse_package_head(self,data: bytes) -> Tuple[Optional[dict], Optional[bytes]]: """ @@ -255,19 +275,6 @@ class SocketClientApp(QMainWindow): 'result_code': result_code }, data[HEADER_SIZE:] - def receive_data(self,length: int): - """ - 从socket接收指定长度的数据 - """ - data = bytearray() - while len(data) < length: - chunk = self.socket.recv(length - len(data)) - if not chunk: - raise ConnectionError("Connection closed") - data.extend(chunk) - print(f"data size {len(data)}") - return bytes(data) - def process_packet(self): """ 循环接收数据,直到接收完整 """ try: @@ -312,7 +319,7 @@ class SocketClientApp(QMainWindow): """ 获取数据并绘制 """ try: self.status_bar.showMessage("状态: 正在获取数据...") - self.socket.sendall(bytes([0xAA,0x55,0xAA,0x01,0x00,0x00,0x01,0x00,0x77,0x01,0x00,0x01,0x00,0x00,0x00])) # 发送数据 + self.socket.write(bytes([0xAA,0x55,0xAA,0x01,0x00,0x00,0x01,0x00,0x77,0x01,0x00,0x01,0x00,0x00,0x00])) # 发送数据 data = self.process_packet() # 接收所有数据 data = np.frombuffer(data, dtype=np.int32) # 根据实际数据格式转换 for i in range(min(100, len(data))): # 确保不超过数据长度 @@ -379,7 +386,7 @@ class SocketClientApp(QMainWindow): print(f"Upgrade length: {upgrade_len}, CRC: {crc}") print(f"Total packet size: {len(full_packet)} bytes") - self.socket.sendall(full_packet) + self.socket.write(full_packet) print("Upgrade packet ready to send (commented out actual send code)") except Exception as e: print(f"Upgrade failed: {str(e)}") @@ -425,11 +432,11 @@ class SocketClientApp(QMainWindow): print(f"Upgrade length: {upgrade_len}, CRC: {crc}") print(f"Total packet size: {len(full_packet)} bytes") - self.socket.sendall(full_packet) + self.socket.write(full_packet) sleep(15) self.socket.close() self.connect_to_server() - self.socket.sendall(full_packet) + self.socket.write(full_packet) print("Upgrade packet ready to send (commented out actual send code)") except Exception as e: print(f"Upgrade failed: {str(e)}")