You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python客户端连接Flutter Android WebSocket服务卡在create_connection

问题分析与解决方案:Flutter TCP服务器与Python WebSocket客户端连接异常

问题描述

在Android设备上用Flutter搭建了TCP服务器,Windows平台的Python程序作为客户端发起连接,但代码始终卡在create_connection步骤无法继续执行。Flutter调试控制台能打印出客户端的WebSocket连接请求信息,但Python客户端一直停滞在连接阶段。

涉及代码

client.py(Python客户端)

from websocket import create_connection

try:
    ws = create_connection("ws://192.168.100.6:5000")
    print("Connected")

    result = ws.send('Hey'.encode('utf-8'))

    ws.close()
except Exception as e: print(e)

main.dart(Flutter入口)

// import 'package:flutter/material.dart';
import 'package:web_socket_app/Server/tcp_server.dart';
import 'package:flutter/material.dart';

void main() async {
  try {
    TCPServer tcp = TCPServer(port: 5000);
    await tcp.startServer();
  } catch (e) {
    print(e);
  }
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(body: Text('hey')),
    );
  }
}

tcp_server.dart(Flutter TCP服务器实现)

import 'dart:convert';
import 'dart:io';

class TCPServer {
  late ServerSocket socket;

  final int port;

  TCPServer({required this.port});

  Future<ServerSocket> bindTo(int port) async {
    return ServerSocket.bind('192.168.100.6', port);
  }

  get getInstance => socket;

  Future<void> startServer() async {
    try {
      await bindTo(port).then((server) {
        print('Server started at ${server.address}:${server.port}');
        server.listen((client) async {
          client.listen((event) {
            print("Listening...");
            print(utf8.decode(event));
            // print('received');
            client.write('received');
          });
        });
      });
    } catch (err) {
      print(err);
    }
  }
}

核心原因

协议不匹配:Flutter端实现的是原始TCP服务器,但Python客户端使用WebSocket协议发起连接。WebSocket是基于TCP的应用层协议,需要完成特定的握手流程才能建立有效连接,原始TCP服务器无法解析WebSocket的握手请求,导致客户端一直等待服务器响应,从而停滞。

解决方案

提供两种适配方案,选择其中一种即可:

方案1:将Flutter端改为WebSocket服务器

修改tcp_server.dart,使用dart:io的WebSocket相关API实现标准WebSocket服务:

import 'dart:convert';
import 'dart:io';

class WebSocketServer {
  final int port;

  WebSocketServer({required this.port});

  Future<void> startServer() async {
    try {
      final server = await HttpServer.bind('192.168.100.6', port);
      print('WebSocket服务器启动在 ${server.address}:${server.port}');
      await for (final request in server) {
        if (request.uri.path == '/') {
          // 升级HTTP请求为WebSocket连接
          WebSocketTransformer.upgrade(request).then((ws) {
            print('客户端已连接');
            ws.listen((message) {
              print('收到消息: $message');
              ws.send('received');
            }, onDone: () {
              print('客户端断开连接');
            });
          });
        } else {
          request.response.statusCode = HttpStatus.notFound;
          request.response.close();
        }
      }
    } catch (err) {
      print(err);
    }
  }
}

同时修改main.dart中的服务器实例化逻辑:

import 'package:flutter/material.dart';
import 'package:web_socket_app/Server/websocket_server.dart';

void main() async {
  try {
    WebSocketServer wsServer = WebSocketServer(port: 5000);
    await wsServer.startServer();
  } catch (e) {
    print(e);
  }
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(body: Text('WebSocket服务器运行中')),
    );
  }
}

方案2:将Python客户端改为TCP客户端

修改client.py,使用Python原生socket库直接建立TCP连接:

import socket

try:
    # 创建TCP套接字并连接
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.100.6', 5000))
    print("已连接")

    # 发送数据
    s.send('Hey'.encode('utf-8'))

    # 接收服务器响应
    response = s.recv(1024)
    print(f"服务器响应: {response.decode('utf-8')}")

    s.close()
except Exception as e:
    print(e)

额外注意事项

  • 确保Android设备与Windows电脑处于同一局域网,且设备IP地址正确
  • 在AndroidManifest.xml中添加必要的网络权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • 检查Android设备的防火墙设置,确保5000端口允许外部连接

内容的提问来源于stack exchange,提问作者Catalina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:50:47