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

Dart中Socket连接交易终端时TCP连接维护及响应获取问题

问题解决:Dart TCP连接交易终端无法获取支付响应

核心问题

你代码里的致命问题是发送请求后立刻调用了socket.close()——支付终端处理交易需要时间(用户刷卡、输密码等操作都要耗时),此时终端还没生成响应,连接就被你主动断开了,自然收不到结果。另外还有个潜在问题:如果sentData是十六进制格式的终端指令,你用hex.encode()会把字符串转成ASCII字节流,这不符合终端的协议要求,应该用hex.decode()把十六进制字符串转成原始字节数组。

修复方案

  1. 取消发送后立即关闭socket的操作,改为收到终端响应后再关闭连接
  2. 监听socket的错误和完成事件,避免资源泄漏
  3. 添加超时机制,防止终端无响应时程序一直挂起
  4. 修正字节转换的错误(如果sentData是十六进制指令的话)

修改后的代码

import 'dart:convert';
import 'dart:io';
import 'package:convert/convert.dart';

void connectTerminal(String sentData) async{
  const String ipAddv4='192.168.1.111';
  const int termPort= 9182;
  const int timeoutSeconds = 60; // 支付超时时间,根据终端协议调整

  try{
    final socket = await Socket.connect(ipAddv4, termPort).timeout(Duration(seconds: timeoutSeconds));
    print('connection established');

    // 修正:如果sentData是十六进制格式的指令,用decode转成字节数组
    List<int> message = hex.decode(sentData);
    socket.add(message);
    print('Sent request to terminal');

    // 监听响应
    socket.listen(
      (List<int> data){
        final response = hex.encode(data); // 转成十六进制字符串方便查看
        print('Received response from terminal: $response');
        // 收到响应后关闭连接
        socket.close();
      },
      onError: (error){
        print('Socket error: $error');
        socket.close();
      },
      onDone: (){
        print('Socket connection closed');
      },
    );

    // 添加全局超时,防止终端一直不响应
    Future.delayed(Duration(seconds: timeoutSeconds), (){
      if(socket.isOpen){
        print('Payment timeout, closing connection');
        socket.close();
      }
    });

  } catch(e){
    print('Error: $e');
  }
}

额外说明

  • 不同交易终端的协议可能要求保持长连接,或者交易完成后才会返回响应,你需要对照终端的官方协议文档确认响应的触发条件
  • 如果终端会返回多个数据包(比如先返回“正在处理”的中间响应,再返回最终结果),你需要在listen回调里拼接数据,直到收到完整的响应后再关闭连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:12:41