Dart中Socket连接交易终端时TCP连接维护及响应获取问题
问题解决:Dart TCP连接交易终端无法获取支付响应
核心问题
你代码里的致命问题是发送请求后立刻调用了socket.close()——支付终端处理交易需要时间(用户刷卡、输密码等操作都要耗时),此时终端还没生成响应,连接就被你主动断开了,自然收不到结果。另外还有个潜在问题:如果sentData是十六进制格式的终端指令,你用hex.encode()会把字符串转成ASCII字节流,这不符合终端的协议要求,应该用hex.decode()把十六进制字符串转成原始字节数组。
修复方案
- 取消发送后立即关闭socket的操作,改为收到终端响应后再关闭连接
- 监听socket的错误和完成事件,避免资源泄漏
- 添加超时机制,防止终端无响应时程序一直挂起
- 修正字节转换的错误(如果
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
相关产品推荐
相关产品推荐

