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

Flutter调用NodeJS登录接口出现_ClientSocketException连接超时问题

Flutter调用NodeJS登录出现Connection timed out异常排查

问题描述

尝试通过Flutter调用NodeJS实现登录功能,点击登录按钮时抛出异常:_ClientSocketException (Connection timed out)。

环境信息

  • PC IP地址:192.168.8.100,执行netstat -a显示监听192.168.8.100:139
  • 调试用手机IP:192.168.8.101

相关代码

config.dart

class Config {
  static const String appName = 'Shopping app';
  static const String apiURL = '192.168.8.101:4000';
  static const String loginAPI = '/users/login';
  static const String registerAPI = '/users/register';
  static const String userProfileAPI = '/users/user-Profile';
}

api_services.dart

class APIService {
  static var client = http.Client();

  static Future<bool> login(LoginRequestModel model) async {
    Map<String, String> requestHeaders = {
      'Content-Type': 'application/json',
    };

    var url = Uri.http(Config.apiURL, Config.loginAPI);

    var response = await client.post(
      url,
      headers: requestHeaders,
      body: jsonEncode(model.toJson()),
    );

    if (response.statusCode == 200) {
      await SharedService.setLoginDetails(loginResponseJson(response.body));
      return true;
    } else {
      return false;
    }
  }

  static Future<RegisterResponseModel> register(
      RegisterRequestModel model) async {
    Map<String, String> requestHeaders = {
      'Content-Type': 'application/json',
    };

    var url = Uri.http(Config.apiURL, Config.registerAPI);

    var response = await client.post(
      url,
      headers: requestHeaders,
      body: jsonEncode(model.toJson()),
    );

    return registerResponseJson(response.body);
  }
}

login.dart

FormHelper.submitButton(
  'Login',
  btnColor: const Color.fromARGB(255, 25, 19, 83),
  borderColor: Colors.white,
  borderRadius: 10,
  () {
    print('Login');
  
    if (validateAndSave()) {
      setState(() {
        isApiCallProcess = true;
      });
    
      LoginRequestModel model = LoginRequestModel(
        username: username!,
        password: password!,
      );

      APIService.login(model).then(
        (response) {
          setState(() {
            isApiCallProcess = false;
          });

        if (response) {
          Navigator.of(context).pushNamedAndRemoveUntil(
              homeRoute, (route) => false);
        } else {
          FormHelper.showSimpleAlertDialog(
            context,
            Config.appName,
            'Invalid credentials',
            'OK',
            () {
              Navigator.of(context).pop();
              },
            );
          }
        },
      );
    }
  },
),

问题分析与解决方案

1. API地址配置错误

NodeJS服务运行在PC上(IP 192.168.8.100),但Config中的apiURL写的是手机的IP 192.168.8.101:4000,导致Flutter请求指向手机本身,而非PC上的NodeJS服务。

修正方法:将Config中的apiURL改为PC的IP和NodeJS服务端口:

static const String apiURL = '192.168.8.100:4000';

2. NodeJS服务监听范围问题

若NodeJS服务仅监听localhost(127.0.0.1),则只有PC本地能访问,手机无法通过局域网IP连接。

修正方法:启动NodeJS服务时指定监听0.0.0.0或PC的局域网IP,确保局域网内设备可访问:

// NodeJS示例代码
app.listen(4000, '0.0.0.0', () => {
  console.log('Server running on http://192.168.8.100:4000');
});

3. PC防火墙拦截请求

PC防火墙可能阻止了手机对4000端口的访问。

解决方法:在PC防火墙中添加入站规则,允许4000端口的TCP连接。

4. 确认NodeJS服务监听状态

执行netstat -a未看到4000端口监听,说明NodeJS服务可能未启动或未在4000端口监听。

验证方法:重启NodeJS服务,执行netstat -a | findstr "4000"(Windows)或netstat -a | grep 4000(Linux/macOS),确认4000端口处于监听状态。

5. 测试网络连通性

用手机浏览器访问http://192.168.8.100:4000/users/login(GET请求可能返回405,但只要不显示无法连接,就说明网络通畅),排除Flutter代码的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:35:21