MALOUDA-PSA 2024-11-11 21:58 采纳率: 85.6%
浏览 83
已结题

调用libcurl库的curl_easy_perform函数后,程序崩溃

调用libcurl库的curl_easy_perform函数后,程序崩溃


#include "sina.h"
#include <string>

#define HTTP_GET "GET"
#define HTTP_PUT "PUT"
#define HTTP_HEAD "HEAD"
#define HTTP_POST "POST"
#define HTTP_DELETE "DELETE"
#define HTTP_RET_OK "HTTP/1.1 200 OK\r\n"

#define SINA_HOST "hq.sinajs.cn"
#define SINA_PORT 80

#define STEPTIME 100


std::string truncateToLastNewline(const std::string& str) {
    size_t pos = str.find_last_of('\n');
    if (pos != std::string::npos) {
        return str.substr(0, pos + 1); // 包含最后的'\n'字符
    }
    return str; // 如果没有'\n',原样返回字符串
}



size_t callback_get_head(void* ptr, size_t size, size_t nmemb, void* userp)
{
    //    strcat((char*)userp, (char*)ptr);

    //    return size * nmemb; //必须返回这个大小, 否则只回调一次
    char* str = (char*)userp;
    if (str == nullptr) {
        return 0; // 如果 userp 是 NULL,则不进行任何操作
    }

    size_t len = strlen(str);
    size_t newlen = len + size * nmemb;

    //if (len==0)
    //{
    //    return 0;

    //}

    // 确保有足够的空间来存储新的数据
    if (newlen > len) {
        str = (char*)realloc(str, newlen + 1); // +1 for null terminator
        if (str == nullptr) {
            return 0; // realloc 失败
        }
        userp = str; // 更新 userp 到新分配的内存
    }

    memcpy(str + len, ptr, size * nmemb);
    str[newlen] = '\0'; // 添加 null 终止符

    return size * nmemb;
}

static char connect_cloud(char* pc_ret, const char* host_addr, const int portno,
    const char* pc_method, struct curl_slist* http_headers)
{
    CURL* curl;
    CURLcode res = CURLE_GOT_NOTHING;

    assert((pc_ret != NULL) && (host_addr != NULL) && (pc_method != NULL));

    //curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if (!curl) {
        fprintf(stderr, "--- curl init Error!\n");
        return 0;
    }

    curl_easy_setopt(curl, CURLOPT_URL, host_addr);
    curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);     //设置超时, 单位为秒.
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);     //屏蔽其它信号, makes libcurl NOT ask the system to ignore SIGPIPE signals
    curl_easy_setopt(curl, CURLOPT_HEADER, 1L);         //下载数据包括HTTP头部, The default value for this parameter is 0.

#if (CURL_DBG == 1)
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);    //调试用: 显示交互明细,
#endif

/*    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Accept: application/json");
        headers = curl_slist_append(headers, "Content-Type: application/json");
        headers = curl_slist_append(headers, "charsets: utf-8");

    headers = curl_slist_append(headers, "Referer: http://finance.sina.com.cn");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    curl_slist_free_all(headers);
*/

//    header_list = curl_slist_append(header_list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko");

//    header_list = curl_slist_append(header_list, "Content-Type:application/x-www-form-urlencoded; charset=UTF-8");
//    header_list = curl_slist_append(header_list, "Referer:http://finance.sina.com.cn");

//    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);


#if 1
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, pc_method);

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_get_head); //下载数据的回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, pc_ret);                                //下载数据的指针

    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_headers);    //多行的HTTP头部

    //curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); //连接超时限制
    //curl_easy_setopt(curl, CURLOPT_TIMEOUT, 80); //整个CURL操作的超时限制

    // 强制使用 IPv4
    curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

#endif

    res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
        return 0;
    }

    curl_easy_cleanup(curl);

    return 1;
}


int sina_get_stock(char* pc_ret, const char* pc_stockid)
{
    char pc_url[200], ret;
    char* pc_stock = new char[40];
    memcpy(pc_stock, pc_stockid, 40);

    //组织请求头部, 自动末尾添加'\r\n'
    struct curl_slist* http_headers = NULL;
    http_headers = curl_slist_append(http_headers, "content-type: application/x-www-form-urlencoded;charset=UTF-8");
    http_headers = curl_slist_append(http_headers, "Referer: http://finance.sina.com.cn");
    http_headers = curl_slist_append(http_headers, "charsets: utf-8");

    //发送请求, 再判断返回值
    //url = hq.sinajs.cn/list=sz150013

    int len = strlen(pc_stock); // 计算字符串长度

    // 小写转换为大写
    //for (int i = 0; i < len; i++) {
    //    if (pc_stock[i] >= 'a' && pc_stock[i] <= 'z') {
    //        pc_stock[i] -= 32; // 将小写字母转换为大写
    //    }
    //}

    // 大写转换为小写
    for (int i = 0; i < len; i++) {
        if (pc_stock[i] >= 'A' && pc_stock[i] <= 'Z') {
            pc_stock[i] += 32; // 将大写字母转换为小写
        }
    }

    // 输出转换后的字符串
    puts(pc_stock);

    //char pc_url[BUFFER_SIZE];
    

    // 正确的 snprintf 调用

    sprintf(pc_url, "%s/list=%s", SINA_HOST, pc_stock);

    //pc_url = 0x000000a6028feeb0 "hq.sinajs.cn/list=sh601069"
    //snprintf(pc_url, BUFFER_SIZE, "%s/list=%s", SINA_HOST, pc_stock);

    //snprintf(pc_url, 120, "%s/list=%s", SINA_HOST, pc_stock);
    ret = connect_cloud(pc_ret, pc_url, SINA_PORT, HTTP_GET, http_headers);
    //DBG("cloud ret = %s\n", pc_ret);

    //释放 http_headers资源
    curl_slist_free_all(http_headers);
    delete[]pc_stock;

    return(ret);
}

#if 0
/*字符串不同含义的数据用逗号隔开了,按照程序员的思路,顺序号从0开始。
  0:”大秦铁路”,股票名字;
  1:”27.55″,今日开盘价;
  2:”27.25″,昨日收盘价;
  3:”26.91″,当前价格;
  4:”27.55″,今日最高价;
  5:”26.20″,今日最低价;
  6:”26.91″,竞买价,即“买一”报价;
  7:”26.92″,竞卖价,即“卖一”报价;
  8:”22114263″,成交的股票数,由于股票交易以一百股为基本单位,所以在使用时,通常把该值除以一百;
  9:”589824680″,成交金额,单位为“元”,为了一目了然,通常以“万元”为成交金额的单位,所以通常把该值除以一万;
  10:”4695″,“买一”申请4695股,即47手;
  11:”26.91″,“买一”报价;
  12:”57590″,“买二”
  13:”26.90″,“买二”
  14:”14700″,“买三”
  15:”26.89″,“买三”
  16:”14300″,“买四”
  17:”26.88″,“买四”
  18:”15100″,“买五”
  19:”26.87″,“买五”
  20:”3100″,“卖一”申报3100股,即31手;
  21:”26.92″,“卖一”报价
  (22, 23), (24, 25), (26,27), (28, 29)分别为“卖二”至“卖四的情况”
  30:”2008-01-11″,日期;
  31:”15:05:32″,时间;*/
#endif

void stock_parse(stock_info_t* stock, const char* pc_data)
{
    char* pc_str, * pc_str1;
    int i;

    assert((stock != NULL) && (pc_data != NULL));

    // 查找 HTTP_RET_OK
    pc_str = strstr((char*)pc_data, HTTP_RET_OK);
    if (pc_str) {
        pc_str += strlen(HTTP_RET_OK);

        // 查找 \r\n\r\n
        pc_str = strstr(pc_str, "\r\n\r\n");
        if (pc_str) {
            pc_str += 4;

            // 查找第一个逗号
            pc_str = strchr(pc_str, ',');
            if (pc_str == NULL) {
                return;
            }
            pc_str++;

            for (i = 0; i < 5; i++) {
                pc_str1 = strchr(pc_str, ',');
                if (pc_str1) {
                    *pc_str1 = '\0';
                    switch (i) {
                    case 0: stock->price_open = atof(pc_str); break;    // 今开
                    case 1: stock->price_refclose = atof(pc_str); break;    // 昨收
                    case 2: stock->price_close = atof(pc_str); break;    // 当前
                    case 3: stock->price_high = atof(pc_str); break;    // 今高
                    case 4: stock->price_low = atof(pc_str); break;    // 今低
                    }

                    pc_str = pc_str1 + 1;    // 指向下个有效数据
                }
                else {
                    break;  // 无法找到更多的逗号,退出循环
                }
            }
        }
    }
}

上面这个代码在LINUX上跑好几年了,没问题,可是在WINDOWS10上就崩溃,具体是在 res = curl_easy_perform(curl); 这一行进去后崩溃的,无法运行到下一句 if(res != CURLE_OK) , 各种手段都试过了,不知道怎么解决,和找到出错的原因

  • 写回答

1条回答 默认 最新

  • 无疆76 2024-11-11 21:59
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    这个问题可能是由于多种原因导致的,包括环境问题、库的问题或者代码的问题。下面是一些可能的解决步骤和排查方法:

    1. 确认库的安装和版本:确保在Windows上正确安装了libcurl库,并且版本与在Linux上使用的版本相同或兼容。不同版本的库之间可能存在差异,可能导致在迁移过程中出现兼容性问题。
    2. 动态链接库(DLL)问题:确认libcurl的动态链接库(DLL)在Windows上是否正确配置。有时候,如果DLL文件缺失或者版本不匹配,可能会导致程序崩溃。确保所有必需的DLL文件都包含在程序的部署中,并且与你的应用程序兼容。
    3. 编译和链接问题:确认在Windows上的编译和链接设置与在Linux上的设置一致。不同的操作系统和编译器设置可能会导致一些不可预见的问题。
    4. 内存问题:检查你的代码是否有内存泄漏或者未初始化的内存访问等问题。这些问题可能会导致程序在运行时崩溃。
    5. 调试:使用调试器来查看程序崩溃时的具体情况。这可以帮助你定位到具体的问题所在。查看调用栈和变量的值,以确定是哪部分代码导致了崩溃。
    6. 日志和错误输出:增加更多的日志和错误输出,以帮助诊断问题。在curl_easy_perform之后增加错误检查,并输出更多的信息,以便了解发生了什么。
    7. 环境问题:确认你的Windows环境是否配置了所有必要的环境变量和依赖项,以便程序能够正常运行。
    8. 代码问题:仔细检查你的代码,特别是与curl相关的部分,确保没有逻辑错误或语法错误。有时候,简单的拼写错误或逻辑错误也可能导致程序崩溃。
    9. 更新和修复:检查是否有libcurl的更新或修复补丁可供下载。有时候,问题可能是由于库本身的缺陷导致的,更新到最新版本可能可以解决问题。

    通过上述步骤,你应该能够定位并解决问题。如果问题仍然存在,你可能需要更深入地分析代码和环境配置,或者寻求更专业的帮助。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 11月20日
  • 已采纳回答 11月12日
  • 创建了问题 11月11日