c语言实现一个简易的curl工具

前言


使用c语言,基于 libcurl4-openssl-dev libcjson-dev 库,实现一个建议的 curl post 工具

正文


  1. 环境准备

我的环境是 debian12

# 更新本地apt库
apt update

# 安装编译环境
apt install build-essential

# 验证 gcc 版本
gcc --version
# gcc (Debian 12.2.0-14+deb12u1) 12.2.0
# Copyright (C) 2022 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.  There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# 运行apt list,发现已经安装了 libcurl4-openssl-dev
apt list|grep libcurl4-openssl-dev

# 安装 libcjson-dev
apt install libcjson-dev
  1. 代码
    c语言post_client
    post_example.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <cjson/cJSON.h>

// 回调函数,用于处理响应数据
size_t write_callback(void *contents, size_t size, size_t nmemb, char **response) {
    size_t realsize = size * nmemb;
    *response = realloc(*response, strlen(*response) + realsize + 1);
    if (*response == NULL) {
        fprintf(stderr, "Failed to allocate memory\n");
        return 0;
    }
    strncat(*response, (char*)contents, realsize);
    return realsize;
}

int post_request(const char *url, const char *post_data) {
    CURL *curl;
    CURLcode res;
    long http_code = 0;
    char *response = NULL;

    curl = curl_easy_init();
    if(curl) {
        // 设置 URL
        curl_easy_setopt(curl, CURLOPT_URL, url);
        // 设置为 POST 请求
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        // 设置 POST 数据
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
        // 设置请求头
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // 设置回调函数
        response = calloc(1, 1);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        // 执行请求
        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        } else {
            // 获取 HTTP 状态码
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
            printf("HTTP status code: %ld\n", http_code);
            
            printf("response: %s\n", response);

            // 解析 JSON 响应
            cJSON *root = cJSON_Parse(response);
            if (root) {
                cJSON *status = cJSON_GetObjectItem(root, "result");
                if (cJSON_IsString(status) && status->valuestring != NULL) {
                    printf("result: %s\n", status->valuestring);
                }
                cJSON_Delete(root);
            } else {
                fprintf(stderr, "Failed to parse JSON response\n");
            }
        }

        // 清理资源
        curl_easy_cleanup(curl);
        curl_slist_free_all(headers);
        free(response);
    }
    return (int)http_code;
}

int main() {
    const char *url = "http://127.0.0.1:12121/tst";
    const char *post_data = "{\"key\": \"value\"}";

    post_request(url, post_data);
    return 0;
}

python3 flask http server
http_server.py

from flask import Flask , jsonify, request, Response

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

@app.route('/tst', methods=['POST'])
def tst():
    data = request.get_json()
    print(data)
    res = {
        "status":"200",
        "error": None,
        "result": "success"
    }
    return jsonify(res)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=12121, debug=True)
  1. 编译
gcc -o post_example post_example.c -lcurl -lcjson
# 编译成功后,生成可执行文件 post_example
  1. 执行
    终端1 启动http server
python3 http_server.py

终端2 发送post

./post_example

# 返回打印如下
HTTP status code: 200
response: {
  "error": null,
  "result": "success",
  "status": "200"
}

result: success
posted @ 2025-05-29 16:54  BrianSun  阅读(64)  评论(0)    收藏  举报