diff --git a/gateway_config.py b/gateway_config.py index 75d350e..9171777 100644 --- a/gateway_config.py +++ b/gateway_config.py @@ -294,8 +294,33 @@ class TcpServerThread(QThread): def stop(self): self.running = False + try: + if self.sock: + self.sock.close() # 打断accept轮询, run循环立即退出 + except Exception: + pass + self._close_all_clients() self.wait(3000) + def _close_all_clients(self): + """主动断开所有已连接客户端(网关模组的TCP链路随之释放, 对端能立刻感知断开)。""" + with self.conn_lock: + conns = list(self._conns.keys()) + self._conns.clear() + self.conn = None + self.target_ip = None + for conn in conns: + try: + conn.shutdown(socket.SHUT_RDWR) + except Exception: + pass + try: + conn.close() + except Exception: + pass + self._hexbufs.clear() + self._push_ip_list() + class GatewayConfigTool(QMainWindow): def __init__(self): @@ -315,7 +340,7 @@ class GatewayConfigTool(QMainWindow): self.refresh_ports() def init_ui(self): - self.setWindowTitle("网关配置工具(宽带版 V1.3.0)") + self.setWindowTitle("网关配置工具(宽带版 V1.3.1)") self.setWindowIcon(QIcon(resource_path("物联网网关.png"))) self.setMinimumSize(940, 640) self.resize(1000, 700) @@ -795,6 +820,8 @@ class UpgradeDialog(QDialog): self._timer = QTimer() self.channel = 'serial' # 升级通道: serial / tcp self.tcp_thread = None + self.ser = None # 升级通道串口对象(独立于主界面串口) + self._serial_rx = None # 升级串口接收线程 self._window = 8 # TCP模式每批包数(窗口流控) self._window_start = 0 # 当前批次首包序号(超时重发用) self._retry_cnt = 0 # TCP模式超时重发计数 @@ -832,7 +859,7 @@ class UpgradeDialog(QDialog): # 通道选择 + TCP监听 cfg_layout.addWidget(QLabel("通道:"), 2, 0) self.combo_channel = QComboBox() - self.combo_channel.addItems(["串口", "TCP(Cat1)"]) + self.combo_channel.addItems(["串口", "TCP(Cat1)", "TCP(ETH)"]) self.combo_channel.currentIndexChanged.connect(self._on_channel_changed) cfg_layout.addWidget(self.combo_channel, 2, 1) tcp_row = QHBoxLayout() @@ -1263,6 +1290,7 @@ class UpgradeDialog(QDialog): done = max(self._sent) + 1 self.progress.setValue(min(int(done * 100.0 / self._pkg_num), 100)) self.status_lbl.setText(f"{done}/{self._pkg_num} 包") + self._timer.start(3000) # 批次发完重置超时: 防止上次定时器虚假触发(REQ已处理仍判超时) if len(self._sent) >= self._pkg_num: self._finish() @@ -1309,8 +1337,25 @@ class UpgradeDialog(QDialog): self._cancel_upgrade() else: self._release_session() - if self.ser and self.ser.is_open: - self._toggle_serial() + # 升级TCP通道: 停止监听并主动断开已连接的客户端, 释放网关模组建立的TCP链路 + if self.tcp_thread is not None: + if self.tcp_thread.isRunning(): + self.tcp_thread.stop() + self.tcp_thread = None + self.btn_tcp_listen.setText("开始监听") + # 串口通道: 关闭升级页面打开的串口 + if self.ser is not None: + if self._serial_rx is not None: + self._serial_rx.stop() + self._serial_rx = None + try: + self.ser.close() + except Exception: + pass + self.ser = None + self.btn_serial_open.setText("打开串口") + self.serial_status_lbl.setText("未打开") + self.serial_status_lbl.setStyleSheet("color:#909090;") self._reset_ui() event.accept()