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

使用GSMComm库获取USSD结果遇超时:代码排查与方案咨询

问题:GSM调制解调器USSD查询超时(No data received from phone)

背景与代码

你尝试用GSMComm库结合ASP.NET Web Forms和C#开发SIM卡余额查询功能,调试确认调制解调器已连接,但调用ExecAndReceiveMultiple时出现超时错误:No data received from phone after waiting for 29999 / 30030 ms。以下是你的代码:

public string SendUssdRequest2(string request) { 
    comm = ConnectAndGetComm(); 
    string data = TextDataConverter.StringTo7Bit(request); 
    string msg = ""; 
    var asPDUencoded = Calc.IntToHex(TextDataConverter.SeptetsToOctetsInt(data)); 
    try { 
        IProtocol protocol = comm.GetProtocol(); 
        string gottenString = protocol.ExecAndReceiveMultiple("AT+CUSD=1," + asPDUencoded + ",15"); 
        var re = new Regex(".*?"); 
        int i = 0; 
        if (!re.IsMatch(gottenString)) { 
            do { 
                protocol.Receive(out gottenString); 
                ++i; 
            } while (!(i >= 5 || re.IsMatch(gottenString) || gottenString.Contains("\r\nOK") || gottenString.Contains("\r\nERROR") || gottenString.Contains("\r\nDONE"))); 
        } 
        string m = re.Match(gottenString).Value.Trim('"'); 
        return PduParts.Decode7BitText(Calc.HexToInt(m)); 
    } catch(Exception e) { 
        msg = e.Message; 
    } finally { 
        comm.ReleaseProtocol(); 
    } 
    return msg; 
}

代码中的明显问题

  1. 无效的正则表达式:var re = new Regex(".*?");这个正则是匹配任意字符的非贪婪模式,完全无法捕捉USSD的标准响应格式(比如+CUSD: 1,"余额信息",15),导致循环一直等待“匹配成功”,最终触发超时。

  2. USSD指令格式错误:

    • 拼接的AT指令缺少双引号包裹PDU内容,正确格式应为AT+CUSD=1,"<PDU_HEX>",15,你当前的代码会生成AT+CUSD=1,xxxxxx,15,调制解调器无法识别这种格式的指令。
    • 部分运营商或调制解调器对CUSD第三个参数(编码方案)要求不同,15代表GSM 7位编码,但如果运营商采用UCS2编码,需要改为8。
  3. 响应处理逻辑不合理:

    • ExecAndReceiveMultiple适合处理指令执行后直接返回多条响应的场景,但USSD响应是调制解调器主动上报的消息,并非指令执行后的即时返回,用这个方法等待无法捕获到目标响应。

可能的超时原因

除代码问题外,还有这些常见诱因:

  • 调制解调器配置缺失:未提前设置字符集(比如发送AT+CSCS="GSM"确保编码匹配),或未关闭之前的USSD会话(发送AT+CUSD=0)。
  • 串口参数不匹配:即使连接正常,波特率、奇偶校验等参数与调制解调器不一致,也会导致数据接收失败。
  • 运营商响应特性:部分运营商的USSD响应延迟较高,或需要特定的指令前缀/后缀才能触发响应。

修复后的代码示例

这里提供调整后的版本,修正正则、指令格式和响应监听逻辑:

public string SendUssdRequestFixed(string request)
{
    string responseMsg = "";
    comm = ConnectAndGetComm();
    try
    {
        IProtocol protocol = comm.GetProtocol();
        
        // 先设置字符集为GSM,确保编码匹配
        protocol.ExecAndReceive("AT+CSCS=\"GSM\"");
        
        // 正确编码并拼接USSD指令,添加双引号包裹PDU
        string ussdPdu = TextDataConverter.StringTo7Bit(request);
        int octets = TextDataConverter.SeptetsToOctetsInt(ussdPdu);
        string hexPdu = Calc.IntToHex(octets);
        string atCommand = $"AT+CUSD=1,\"{hexPdu}\",15";
        
        // 发送指令后不等待即时返回,改为监听主动上报的响应
        protocol.Send(atCommand);
        
        // 循环监听响应,每次等待5秒,最多尝试10次
        int retryCount = 0;
        string receivedData;
        var ussdRegex = new Regex(@"\+CUSD:\s*1,""(.*?)""", RegexOptions.Singleline);
        
        do
        {
            if (protocol.Receive(out receivedData, 5000))
            {
                Match match = ussdRegex.Match(receivedData);
                if (match.Success)
                {
                    string encodedBalance = match.Groups[1].Value;
                    responseMsg = PduParts.Decode7BitText(Calc.HexToInt(encodedBalance));
                    break;
                }
                else if (receivedData.Contains("\r\nERROR"))
                {
                    responseMsg = "USSD指令执行失败";
                    break;
                }
            }
            retryCount++;
        } while (retryCount < 10);
        
        if (string.IsNullOrEmpty(responseMsg))
        {
            responseMsg = "未收到USSD响应";
        }
    }
    catch (Exception ex)
    {
        responseMsg = $"错误:{ex.Message}";
    }
    finally
    {
        comm.ReleaseProtocol();
    }
    return responseMsg;
}

替代库与实现方案

如果GSMComm库兼容性问题难以解决,可以尝试这些方案:

  • 直接使用System.IO.Ports.SerialPort:手动控制串口发送AT指令、逐行监听响应,灵活性更高,适合调试和定制化需求,能直接排查指令和响应的细节问题。
  • GsmCommunication.NET:这是GSMComm的更新分支,针对.NET Framework和.NET Core做了优化,支持更多现代调制解调器。
  • 串口调试工具前置测试:先用PuTTY等串口助手手动发送AT指令测试USSD流程,确认指令格式和响应格式后再编写代码,快速排除硬件或运营商侧的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:58:15