c语言实现一个简易的curl工具
前言
使用c语言,基于 libcurl4-openssl-dev libcjson-dev 库,实现一个建议的 curl post 工具
正文
- 环境准备
我的环境是 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
- 代码
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)
- 编译
gcc -o post_example post_example.c -lcurl -lcjson
# 编译成功后,生成可执行文件 post_example
- 执行
终端1 启动http server
python3 http_server.py
终端2 发送post
./post_example
# 返回打印如下
HTTP status code: 200
response: {
"error": null,
"result": "success",
"status": "200"
}
result: success