本文介绍如何使用阿里云智能语音服务提供的C++ SDK,包括SDK的安装方法及SDK代码示例。

使用说明

  • 当前最新版本:3.0.10,支持Linux及Windows平台。发布日期:2021年06月29日。本文以当前版本为例进行介绍。

  • 请先阅读接口说明,详情请参见 接口说明

下载安装

SDK下载:

可以 下载已经编译完成的SDK ,也可以使用 SDK源码 进行编译。

  • build.sh:示例编译脚本。

  • CMakeLists.txt:示例代码工程的CMakeList文件。

  • demo:示例,语音服务配置文件,如下表所示。

    文件名

    描述

    speechRecognizerDemo.cpp

    一句话识别示例

    speechSynthesizerDemo.cpp

    语音合成示例

    speechTranscriberDemo.cpp

    实时语音识别示例

    speechLongSynthesizerDemo.cpp

    长文本语音合成示例

    test0.wav/test1.wav

    测试音频(16k采样频率、16bit采样位数的音频文件)

  • include:SDK头文件,如下表所示。

    文件名

    描述

    nlsClient.h

    SDK实例

    nlsEvent.h

    回调事件说明

    speechRecognizerRequest.h

    一句话识别

    speechSynthesizerRequest.h

    语音合成/长文本语音合成

    speechTranscriberRequest.h

    实时音频流识别

  • lib:SDK库文件。

  • readme.md:SDK说明。

  • release.log:版本说明。

  • version:版本号。

编译运行:

  1. 安装工具的最低版本要求如下:

    • Cmake 3.1

    • Glibc 2.5

    • Gcc 4.1.2

  2. 在Linux终端运行如下脚本。

    mkdir build
    cd build && cmake .. && make
    cd ../demo #生成示例可执行程序:srDemo(一句话识别)、stDemo(实时语音识别)、syDemo(语音合成)、syLongDemo(长文本语音合成)。
    ./syLongDemo appkey  <yourAccessKey Id> <yourAccessKey Secret>  # 测试使用。

关键接口

  • 基础接口

    • NlsClient:语音处理客户端,利用该客户端可以进行一句话识别、实时语音识别和语音合成的语音处理任务。该客户端为线程安全,建议全局仅创建一个实例。

    • NlsEvent:事件对象,您可以从中获取Request状态码、云端返回结果、失败信息等。

  • 识别接口

    SpeechSynthesizerRequest:语音合成请求对象,用于语音合成及长文本语音合成。

C++ SDK错误码

状态码

状态消息

原因

解决方案

10000001

NewSslCtxFailed

SSL: couldn't create a context!

建议重新初始化。

10000002

DefaultErrorCode

return of SSL_read: error:00000000:lib(0):func(0):reason(0)

建议重新尝试。

return of SSL_read: error:140E0197:SSL routines:SSL_shutdown:shutdown while in init

10000003

SysErrorCode

系统错误。

根据系统反馈的错误信息进行处理。

10000004

EmptyUrl

URL: The url is empty.

传入的URL为空, 请重新填写正确URL。

10000005

InvalidWsUrl

Could not parse WebSocket url:

传入的URL格式错误, 请重新填写正确URL。

10000007

JsonStringParseFailed

JSON: Json parse failed.

JISO格式异常, 请通过日志查看具体的错误点。

10000008

UnknownWsHeadType

WEBSOCKET: unkown head type.

联网失败,请检查本机DNS解析和URL是否有效。

10000009

HttpConnectFailed

HTTP: connect failed.

与云端连接失败,请检查网络后,重试。

10000010

MemNotEnough

内存不足。

请检查内存是否充足。

10000015

SysConnectFailed

connect failed.

联网失败,请检查本机DNS解析和URL是否有效。

10000100

HttpGotBadStatusWith403

Got bad status host=xxxxx line=HTTP/1.1 403 Forbidden

链接被拒,请检查账号特别是token是否过期。

10000101

EvSendTimeout

Send timeout. socket error:

libevent发送event超时,请检查回调中是否有耗时任务,或并发过大导致无法及时处理事件。

10000102

EvRecvTimeout

Recv timeout. socket error:

libevent接收event超时,请检查回调中是否有耗时任务,或并发过大导致无法及时处理事件。

10000103

EvUnknownEvent

Unknown event:

未知的libevent事件,建议重新尝试。

10000104

OpNowInProgress

Operation now in progress

链接正在进行中,建议重新尝试。

10000105

BrokenPipe

Broken pipe

pipe处理不过来,建议重新尝试。

10000110

TokenHasExpired

Gateway:ACCESS_DENIED:The token 'xxx' has expired!

请更新Token。

10000111

TokenIsInvalid

Meta:ACCESS_DENIED:The token 'xxx' is invalid!

请检查token的有效性。

10000112

NoPrivilegeToVoice

Gateway:ACCESS_DENIED:No privilege to this voice! (voice: zhinan, privilege: 0)

此发音人无权使用。

10000113

MissAuthHeader

Gateway:ACCESS_DENIED:Missing authorization header!

请检查账号是否有权限,或并发是否在限度内。

10000120

Utf8ConvertError

utf8ToGbk failed

utf8转码失败,常为系统问题,建议重新尝试。

服务端响应状态码

关于服务状态码,请参见 服务状态码

代码示例

说明

  • 示例中使用了SDK内置的默认外网访问服务URL,如果您使用阿里云上海ECS且需要使用内网访问服务URL,则在创建SpeechSynthesizerRequest的对象中设置内网访问的URL:

    request->setUrl("ws://nls-gateway.cn-shanghai-internal.aliyuncs.com/ws/v1");

  • 示例中将合成的音频保存在文件中,如果您需要播放音频且对实时性要求较高,建议使用流式播放,即边接收语音数据边播放,减少延时,而无需等待合成结束后再处理语音流。

  • 完整示例参见SDK文件中demo目录的speechLongSynthesizerDemo.cpp文件。

#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <ctime>
#include <string>
#include <vector>
#include <fstream>
#include "nlsClient.h"
#include "nlsEvent.h"
#include "speechSynthesizerRequest.h"
#include "nlsCommonSdk/Token.h"
using namespace AlibabaNlsCommon;
using AlibabaNls::NlsClient;
using AlibabaNls::NlsEvent;
using AlibabaNls::LogDebug;
using AlibabaNls::LogInfo;
using AlibabaNls::SpeechSynthesizerRequest;
// 自定义线程参数
struct ParamStruct {
    std::string text;
    std::string token;
    std::string appkey;
    std::string audioFile;
// 自定义事件回调参数
struct ParamCallBack {
    std::string binAudioFile;
    std::ofstream audioFile;
    uint64_t startMs;
//全局维护一个服务鉴权Token和其对应的有效期时间戳,
//每次调用服务之前,首先判断Token是否已经过期,
//如果已经过期,则根据AccessKey ID和AccessKey Secret重新生成一个Token,并更新该全局的Token和其有效期时间戳。
//获取Token具体操作,请参见:https://help.aliyun.com/document_detail/450514.html
//注意:只需在Token即将过期时重新生成即可,所有服务并发可共用一个Token。
std::string g_akId = "";
std::string g_akSecret = "";
std::string g_token = "";
long g_expireTime = -1;
uint64_t getNow() {
    struct timeval now;
    gettimeofday(&now, NULL);
    return now.tv_sec * 1000 * 1000 + now.tv_usec;
int generateToken(std::string akId, std::string akSecret, std::string* token, long* expireTime) {
    NlsToken nlsTokenRequest;
    nlsTokenRequest.setAccessKeyId(akId);
    nlsTokenRequest.setKeySecret(akSecret);
    if (-1 == nlsTokenRequest.applyNlsToken()) {
        // 获取失败原因
        printf("generateToken Failed: %s\n", nlsTokenRequest.getErrorMsg());
        return -1;
    *token = nlsTokenRequest.getToken();
    *expireTime = nlsTokenRequest.getExpireTime();
    return 0;
//@brief SDK在接收到云端返回合成结束消息时,其内部线程上报Completed事件。
//@note 上报Completed事件之后,SDK内部会关闭识别连接通道。
//@param cbEvent 回调事件结构,详见nlsEvent.h。
//@param cbParam 回调自定义参数,默认为NULL,可以根据需求自定义参数。
void OnSynthesisCompleted(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // 演示如何打印/使用用户自定义参数示例。
    printf("OnSynthesisCompleted: %s\n", tmpParam->binAudioFile.c_str());
    // 获取消息的状态码,成功为0或者20000000,失败时对应失败的错误码。
    // 当前任务的task id。
    printf("OnSynthesisCompleted: status code=%d, task id=%s\n", cbEvent->getStatusCode(), cbEvent->getTaskId());
    // 获取服务端返回的全部信息。
    //printf("OnSynthesisCompleted: all response=%s\n", cbEvent->getAllResponse());
//@brief 合成过程发生异常时,SDK内部线程上报TaskFailed事件。
//@note 上报TaskFailed事件后,SDK内部会关闭识别连接通道。
//@param cbEvent 回调事件结构,详见nlsEvent.h。
//@param cbParam 回调自定义参数,默认为NULL,可以根据需求自定义参数。
void OnSynthesisTaskFailed(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // 演示如何打印/使用用户自定义参数示例。
    printf("OnSynthesisTaskFailed: %s\n", tmpParam->binAudioFile.c_str());
    // 当前任务的task id。
    printf("OnSynthesisTaskFailed: status code=%d, task id=%s, error message=%s\n", cbEvent->getStatusCode(), cbEvent->getTaskId(), cbEvent->getErrorMessage());
//@brief 识别结束或发生异常时,会关闭连接通道,SDK内部线程上报ChannelCloseed事件。
//@param cbEvent 回调事件结构,详见nlsEvent.h。
//@param cbParam 回调自定义参数,默认为NULL,可以根据需求自定义参数。
void OnSynthesisChannelClosed(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // 演示如何打印/使用用户自定义参数示例。
    printf("OnSynthesisChannelClosed: %s\n", tmpParam->binAudioFile.c_str());
    printf("OnSynthesisChannelClosed: %s\n", cbEvent->getAllResponse());
    tmpParam->audioFile.close();
    delete tmpParam; //识别流程结束,释放回调参数。
//@brief 文本上报服务端之后,收到服务端返回的二进制音频数据,SDK内部线程通过BinaryDataRecved事件上报给您。
//@param cbEvent 回调事件结构,详见nlsEvent.h。
//@param cbParam 回调自定义参数,默认为NULL,可以根据需求自定义参数。
void OnBinaryDataRecved(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    if(tmpParam->startMs > 0 ) {
        // 说明:一旦获取到语音流,如第一次从服务端返回合成语音流,即可开始进行播放或者其他处理,本示例为保存到本地文件。
        // 第一次收到语音流数据,计算TTS合成首包延迟。另外此处计算首包延迟时也包括了start操作(即本程序连接公共云服务端的时间),而该时间受不同网络因素影响可能有较大差异。
        uint64_t now = getNow();
        printf("first latency = %lld ms, task id = %s\n", (now - tmpParam->startMs) / 1000, cbEvent->getTaskId());
        tmpParam->startMs = 0;
    // 演示如何打印/使用用户自定义参数示例。
    printf("OnBinaryDataRecved: %s\n", tmpParam->binAudioFile.c_str());
    const std::vector<unsigned char>& data = cbEvent->getBinaryData(); // getBinaryData()为获取文本合成的二进制音频数据。
    printf("OnBinaryDataRecved: status code=%d, task id=%s, data size=%d\n", cbEvent->getStatusCode(), cbEvent->getTaskId(), data.size());
    // 以追加形式将二进制音频数据写入文件。
    if (data.size() > 0) {
        tmpParam->audioFile.write((char*)&data[0], data.size());
//@brief 返回tts文本对应的日志信息,增量返回对应的字幕信息。
//@param cbEvent 回调事件结构,详见nlsEvent.h。
//@param cbParam 回调自定义参数,默认为NULL,可以根据需求自定义参数。
void OnMetaInfo(NlsEvent* cbEvent, void* cbParam) {
    ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
    // 演示如何打印/使用用户自定义参数示例。
    printf("OnBinaryDataRecved: %s\n", tmpParam->binAudioFile.c_str());
    printf("OnMetaInfo: task id=%s, respose=%s\n", cbEvent->getTaskId(), cbEvent->getAllResponse());
// 工作线程
void* pthreadFunc(void* arg) {
    // 0:从自定义线程参数中获取token,配置文件等参数。
    ParamStruct* tst = (ParamStruct*)arg;
    if (tst == NULL) {
        printf("arg is not valid\n");
        return NULL;
    // 1:初始化自定义回调参数。
    ParamCallBack* cbParam = new ParamCallBack;
    cbParam->binAudioFile = tst->audioFile;
    cbParam->audioFile.open(cbParam->binAudioFile.c_str(), std::ios::binary | std::ios::out);
    // 2:创建语音识别SpeechSynthesizerRequest对象。
    SpeechSynthesizerRequest* request = NlsClient::getInstance()->createSynthesizerRequest(AlibabaNls::LongTts);
    if (request == NULL) {
        printf("createSynthesizerRequest failed.\n");
        cbParam->audioFile.close();
        return NULL;
    request->setOnSynthesisCompleted(OnSynthesisCompleted, cbParam); // 设置音频合成结束回调函数
    request->setOnChannelClosed(OnSynthesisChannelClosed, cbParam); // 设置音频合成通道关闭回调函数
    request->setOnTaskFailed(OnSynthesisTaskFailed, cbParam); // 设置异常失败回调函数
    request->setOnBinaryDataReceived(OnBinaryDataRecved, cbParam); // 设置文本音频数据接收回调函数
    request->setOnMetaInfo(OnMetaInfo, cbParam); // 设置字幕信息
    request->setAppKey(tst->appkey.c_str());
    request->setText(tst->text.c_str()); // 设置待合成文本,必填参数。文本内容必须为UTF-8编码。
    request->setVoice("siqi");              // 发音人。可选参数,默认是xiaoyun。注意:C++ SDK不支持调用超高清场景对应的发音人(例如"zhiqi"),如需调用请使用restfulAPI方式。
    request->setVolume(50);              // 音量,范围是0~100,可选参数,默认50。
    request->setFormat("wav");             // 音频编码格式,可选参数,默认是wav。支持的格式PCM、WAV和MP3。
    request->setSampleRate(8000);          // 音频采样率:8000/16000。可选参数,默认是16000。
    request->setSpeechRate(0);              // 语速,范围是-500~500,可选参数,默认是0。
    request->setPitchRate(0);              // 语调,范围是-500~500,可选参数,默认是0。
    //request->setEnableSubtitle(true);      //是否开启字幕,非必须,需要注意的是并不是所有发音人都支持字幕功能。
    request->setToken(tst->token.c_str()); // 设置账号校验token,必填参数。
    cbParam->startMs = getNow();
    // 3:start()为异步操作。成功返回BinaryRecv事件。失败返回TaskFailed事件。
    if (request->start() < 0) {
        printf("start() failed. may be can not connect server. please check network or firewalld\n");
        NlsClient::getInstance()->releaseSynthesizerRequest(request); // start()失败,释放request对象
        cbParam->audioFile.close();
        return NULL;
    //4:通知云端数据发送结束。
    //stop()为异步操作,失败返回TaskFailed事件。
    request->stop();
    // 5:识别结束,释放request对象。
    NlsClient::getInstance()->releaseSynthesizerRequest(request);
    return NULL;
// 合成单个文本数据
int speechLongSynthesizerFile(const char* appkey) {
    //获取当前系统时间戳,判断token是否过期。
    std::time_t curTime = std::time(0);
    if (g_expireTime - curTime < 10) {
        printf("the token will be expired, please generate new token by AccessKey-ID and AccessKey-Secret.\n");
        if (-1 == generateToken(g_akId, g_akSecret, &g_token, &g_expireTime)) {
            return -1;
    ParamStruct pa;
    pa.token = g_token;
    pa.appkey = appkey;
    // 注意:Windows平台下,合成文本中如果包含中文,请将本CPP文件设置为带签名的UTF-8编码或者GB2312编码。
    pa.text = "今天天气很棒,适合去户外旅行.";
    pa.audioFile = "syAudio.wav";
    pthread_t pthreadId;
    // 启动一个工作线程,用于识别。
    pthread_create(&pthreadId, NULL, &pthreadFunc, (void *)&pa);
    pthread_join(pthreadId, NULL);
    return 0;
// 合成多个文本数据
// SDK多线程指一个文本数据对应一个线程,非一个文本数据对应多个线程。
// 示例代码为同时开启2个线程,合成2个文件。
#define AUDIO_TEXT_NUMS 2
#define AUDIO_TEXT_LENGTH 64
#define AUDIO_FILE_NAME_LENGTH 32
int speechLongSynthesizerMultFile(const char* appkey) {
    //获取当前系统时间戳,判断token是否过期。
    std::time_t curTime = std::time(0);
    if (g_expireTime - curTime < 10) {
        printf("the token will be expired, please generate new token by AccessKey-ID and AccessKey-Secret.\n");
        if (-1 == generateToken(g_akId, g_akSecret, &g_token, &g_expireTime)) {
            return -1;
    const char syAudioFiles[AUDIO_TEXT_NUMS][AUDIO_FILE_NAME_LENGTH] = {"syAudio0.wav", "syAudio1.wav"};
    const char texts[AUDIO_TEXT_NUMS][AUDIO_TEXT_LENGTH] = {"今日天气真不错,我想去操作踢足球.", "明天有大暴雨,还是宅在家里看电影吧."};
    ParamStruct pa[AUDIO_TEXT_NUMS];
    for (int i = 0; i < AUDIO_TEXT_NUMS; i ++) {
        pa[i].token = g_token;
        pa[i].appkey = appkey;
        pa[i].text = texts[i];
        pa[i].audioFile = syAudioFiles[i];
    std::vector<pthread_t> pthreadId(AUDIO_TEXT_NUMS);
    // 启动工作线程,同时识别音频文件。
    for (int j = 0; j < AUDIO_TEXT_NUMS; j++) {
        pthread_create(&pthreadId[j], NULL, &pthreadFunc, (void *)&(pa[j]));
    for (int j = 0; j < AUDIO_TEXT_NUMS; j++) {
        pthread_join(pthreadId[j], NULL);
    return 0;
int main(int arc, char* argv[]) {
    if (arc < 4) {
        printf("params is not valid. Usage: ./demo <your appkey> <your AccessKey ID> <your AccessKey Secret>\n");
        return -1;
    std::string appkey = argv[1];
    g_akId = argv[2];
    g_akSecret = argv[3];
    // 根据需要设置SDK输出日志,可选。此处表示SDK日志输出至log-Synthesizer.txt,LogDebug表示输出所有级别日志。
    int ret = NlsClient::getInstance()->setLogConfig("log-longsynthesizer", LogDebug);
    if (-1 == ret) {
        printf("set log failed\n");
        return -1;
    //启动工作线程
    NlsClient::getInstance()->startWorkThread(4);
    /// 注意:长文本语音合成目前没有免费试用版,必须开通商业版长文本语音合成之后才能进行测试。
    // 合成单个文本
    speechLongSynthesizerFile(appkey.c_str());
    // 合成多个文本
    // speechLongSynthesizerMultFile(appkey.c_str());
    // 所有工作完成,进程退出前,释放nlsClient。请注意,releaseInstance()非线程安全。
    NlsClient::releaseInstance();
    return 0;
}

常见问题

C++ SDK(3.0及以后版本)使用语音合成和语音识别功能,可以提高GCC5.0以上的编译版本吗?

可以。Linux下支持GCC 4.8.5或以上版本。目前已验证且顺利编译运行的GCC版本包括4.8.5、5.5.0、8.4.0。

为什么链接不到framework?

framework中代码采用Objective-C和C++混合编写而成,所以需要使用.mm后缀文件进行调用,同时请确保工程的头文件路径与库文件路径设置正确。

C++ SDK ASR请求有DNS解析失败的情况导致异常,报错ali-recog-skd.log:AliSpeech_C++SDK(ERROR): GetInetAddressByHostname:252 DNS: resolved timeout.ali-recog-skd.log:AliSpeech_C++SDK(ERROR): start:76 start failed: DNS: resolved timeout..unimrcpserver_current.log: [ERROR] [[./ali/AliRecogChannel.cpp:772,onTaskFailed]]Ali Task start failed Msg :DNS: resolved timeout., start finised."如何解决?

  • 旧版(3.0及以前版本):在高并发或者电脑DNS忙碌的情况下容易出现以上问题,建议您更新到3.1.X版本,或进行再次重启请求。

  • 新版(3.0及以后版本):已经对此问题进行防御,若仍然偶现此问题,则为电脑DNS忙碌,需要再次重启请求。

C++ SDK(新)集成到其他项目中时,将CMakeLists.txt中的add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) 修改为add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1)后编译不通过该如何解决?

除了 CMakeLists.txt ,全工程都需要修改该参数,例如 config/linux.thirdparty.debug.cmake config/linux.thirdparty.release.cmake ,请在全目录搜索 _GLIBCXX_USE_CXX11_ABI 进行修改。

C++ SDK在Windows上使用,报错缺少nlsCommonSdk.dll如何解决?

3.1及以后版本无nlsCommonSdk.dll。

C++ SDK旧版NlsSdkCpp2.0和新版NlsSdkCpp3.X的区别是什么?

NlsSdkCpp2.0版本的SDK每一个请求为一个线程,且接口为同步接口。

NlsSdkCpp3.X版本的SDK内部由第三方库libevent统一处理事件消息,并发性能更强,且接口为异步接口。

C++版的SDK不支持实现C11规范吗? 现在导致项目无法链接SDK该如何解决?

工程默认为 _GLIBCXX_USE_CXX11_ABI=0 ,全工程都需要修改该参数,请在全目录搜索 _GLIBCXX_USE_CXX11_ABI 进行修改。

C++ SDK测试Demo成功,集成项目报错,DNS解析失败,报错 nls-gateway.cn-shanghai.aliyuncs.com dns failed: nodename nor servname provided, or not known如何解决?

  1. SDK中会查看当前设备开启的所有协议族(IPv4、IPv6)进行DNS解析请求, nls-gateway.cn-shanghai.aliyuncs.com 不支持 IPv6,返回解析错误,从而导致SDK DNS解析失败退出。可禁用当前设备的IPv6协议族,后续CppSdk产品改进对这方面进行可配置处理。

  2. 建议您升级到3.1.12及以后版本。

C++ SDK测试Demo可以成功,集成项目报错,网络链接失败,报错[dnsEventCallback:465]Node:0x7f087c001030 ai_canonname: nls-gateway.cn-shanghai.aliyuncs.com.gds.alibabadns.com[dnsEventCallback:477]Node:0x7f087c001030 IpV4:106.15.XX.XX[connectProcess:1329]Node:0x7f087c001030 sockFd:41[connectProcess:1347]Node:0x7f087c001030 new Socket ip:106.15.XX.XX port:443 Fd:41.[socketConnect:1458]Node:0x7f087c001030 Connect failed:Network is unreachable. retry...如何解决?

以上现象为无法连接网络,查看日志发现DNS域名解析出来的IP链接不成功,进一步通过Ping判断网络不通。由于本地拦截DNS解析,导致SDK内部 libevent evdns_getaddrinfo 获得错误的IP。

解决办法:

  • 3.1.12版本以前可将 evdns_getaddrinfo() 手动替换成系统的getaddrinfo()。

  • 3.1.12版本可在 CMakeLists.txt 中修改 add_definitions(-DNLS_USE_NATIVE_GETADDRINFO)

  • 3.1.12及以后版本增加 setDirectHost() 接口,您可以在SDK外部进行DNS解析,获取正确IP后通过该接口设入。

  • 3.1.13及以后版本已解决此问题,若运行时仍存在上述问题,建议调用接口 setUseSysGetAddrInfo(true)

C++ SDK语音合成时传入的文本没有采用UTF-8编码会有什么错误信息?

如果传入的文本没有采用UTF-8编码,在文本中含有中文字符时,语音合成SDK调用start函数会失败,返回错误信息 Socket recv failed, errorCode: 0 。错误码为0表示服务端已经关闭了连接,此时应检查传入的文本是否采用UTF-8编码。

SDK报错“DNS resolved timeout”是什么问题?

查看 /etc/resolv.conf 文件中nameserver的设置,建议增加并优先使用以下配置: nameserver 114.114.114.114