Flutter TCP Socket向Python发送SSID/PSK字符串失败求助
Flutter TCP Socket 传输SSID/PSK到Python服务端问题解决
问题根源
Flutter客户端问题
- 发送数据后立即断开连接,可能导致数据未完全发送就终止连接,服务端无法接收完整数据。
Future.delayed未使用await,导致重连操作会立刻执行,连接状态混乱。- 每次发送单个字段就断开重连,不符合TCP长连接的使用逻辑,也会导致服务端的接收逻辑不匹配。
Python服务端问题
- 每次客户端连接后连续调用三次
recv,但客户端每次仅发送一个字段,多余的recv会阻塞程序,等待不存在的数据。 - 未处理客户端断开连接的情况,
recv返回空字节时未关闭套接字,导致资源浪费。
修正后的代码
Flutter客户端代码
import 'package:flutter/material.dart'; import 'package:tcp_socket_connection/tcp_socket_connection.dart'; class UsersPage extends StatefulWidget { @override _UsersPageState createState() => _UsersPageState(); } class _UsersPageState extends State<UsersPage> { TcpSocketConnection socketConnection = TcpSocketConnection("my_ip", 9000); String message = ""; String ssid = ""; String psk = ""; @override void initState() { super.initState(); startConnection(); } void messageReceived(String msg) { setState(() { message = msg; }); } void startConnection() async { socketConnection.enableConsolePrint(true); if (await socketConnection.canConnect(2000, attempts: 3)) { await socketConnection.connect(2000, messageReceived, attempts: 3); } } // 统一发送数据逻辑 void sendData(String data) async { if (socketConnection.isConnected()) { await socketConnection.sendMessage(data); print("已发送: $data"); } else { print("连接未建立,尝试重连..."); await startConnection(); if (socketConnection.isConnected()) { await socketConnection.sendMessage(data); print("重连后已发送: $data"); } } } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar(title: const Text("WiFi配置")), body: Center( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ TextField( decoration: InputDecoration( hintText: '输入WiFi名称', border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(20.0)), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.blueAccent, width: 1.0), borderRadius: BorderRadius.all(Radius.circular(20.0)), ), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), prefixIcon: Icon(Icons.wifi), ), onChanged: (text) { setState(() { ssid = text; }); }, ), SizedBox(height: 30), TextField( decoration: InputDecoration( hintText: '输入WiFi密码', border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(20.0)), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.blueAccent, width: 1.0), borderRadius: BorderRadius.all(Radius.circular(20.0)), ), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), prefixIcon: Icon(Icons.lock), ), onChanged: (text) { setState(() { psk = text; }); }, ), SizedBox(height: 30), ElevatedButton( onPressed: () => sendData(ssid), child: Text('发送SSID'), ), SizedBox(height: 30), ElevatedButton( onPressed: () => sendData(psk), child: Text('发送PSK'), ), SizedBox(height: 30), ElevatedButton( onPressed: () { if (socketConnection.isConnected()) { socketConnection.disconnect(); setState(() => message = "已断开连接"); } }, child: Text('断开连接'), ), SizedBox(height: 20), Text("服务端回复: $message") ]), ), ), )); } }
改动说明
- 新增
sendData方法,统一处理数据发送逻辑,先检查连接状态,未连接则尝试重连后发送。 - 移除每次发送后的断开重连逻辑,保持长连接,避免连接频繁建立/销毁。
- 添加页面布局优化,增加连接状态提示。
- 修正异步逻辑错误,确保重连操作等待完成后再执行发送。
Python服务端代码
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("0.0.0.0", 9000)) s.listen(5) print("服务端已启动,等待客户端连接...") while True: clientsocket, address = s.accept() print(f"来自 {address} 的连接已建立.") try: while True: data = clientsocket.recv(1024) if not data: # 客户端断开连接 print(f"客户端 {address} 已断开") break received_data = data.decode().strip() print(f"收到数据: {received_data}") # 可选:回复客户端确认接收 clientsocket.sendall(f"已收到: {received_data}".encode()) except Exception as e: print(f"连接异常: {e}") finally: clientsocket.close()
改动说明
- 改为循环接收数据,直到客户端断开连接,匹配长连接场景。
- 处理客户端断开的情况,关闭套接字并跳出循环。
- 添加异常捕获,避免连接异常导致服务端崩溃。
- 增加回复客户端的逻辑,方便客户端确认数据已送达。
进阶优化建议
如果需要同时发送SSID和PSK,建议使用JSON格式一次性传输,避免多次发送:
Flutter端发送JSON
import 'dart:convert'; // 添加发送完整配置的按钮和方法 void sendWifiConfig() async { if (ssid.isNotEmpty && psk.isNotEmpty) { final config = jsonEncode({"ssid": ssid, "psk": psk}); await sendData(config); } }
Python端解析JSON
import json # 在接收循环中解析JSON received_data = data.decode().strip() try: config = json.loads(received_data) print(f"SSID: {config['ssid']}, PSK: {config['psk']}") except json.JSONDecodeError: print(f"非JSON格式数据: {received_data}")
内容的提问来源于stack exchange,提问作者Mesut
相关产品推荐
相关产品推荐

