1、使用 libcurl(推荐)
使用 libcurl
实现 HTTP GET
和 POST
请求是一种非常推荐的做法,因为 libcurl
是一个功能强大、跨平台的网络传输库,支持 HTTP
、HTTPS
、FTP 等多种协议。
1)GET 请求
#include <stdio.h> #include <curl/curl.h> // 回调函数,用于接收服务器响应数据 size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) { size_t total_size = size * nmemb; fwrite(ptr, size, nmemb, stdout); // 打印响应内容到控制台 return total_size; } int main(void) { CURL *curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/get"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); CURLcode res = curl_easy_perform(curl); // 执行请求 if (res != CURLE_OK) { fprintf(stderr, "GET request failed: %s\n", curl_easy_strerror(res)); } curl_easy_cleanup(curl); // 清理资源 } return 0; }
2)POST 请求
#include <stdio.h> #include <curl/curl.h> size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) { size_t total_size = size * nmemb; fwrite(ptr, size, nmemb, stdout); return total_size; } int main(void) { CURL *curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/post"); curl_easy_setopt(curl, CURLOPT_POST, 1L); // 设置 POST 数据 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=Levi&age=25"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { fprintf(stderr, "POST request failed: %s\n", curl_easy_strerror(res)); } curl_easy_cleanup(curl); } return 0; }
2、使用 sockets + HTTP 手写协议
使用sockets更底层,要自己构建 HTTP 请求格式。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netdb.h> #include <arpa/inet.h> #define BUFFER_SIZE 8192 void send_request(const char *host, const char *port, const char *request) { struct hostent *server = gethostbyname(host); if (!server) { fprintf(stderr, "ERROR: No such host\n"); exit(1); } int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("ERROR opening socket"); exit(1); } struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(atoi(port)); memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("ERROR connecting"); close(sockfd); exit(1); } send(sockfd, request, strlen(request), 0); char buffer[BUFFER_SIZE]; int bytes_received; while ((bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) > 0) { buffer[bytes_received] = '\0'; printf("%s", buffer); } close(sockfd); } void http_get() { const char *host = "httpbin.org"; const char *port = "80"; const char *path = "/get"; char request[512]; snprintf(request, sizeof(request), "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "Connection: close\r\n" "\r\n", path, host); send_request(host, port, request); } void http_post() { const char *host = "httpbin.org"; const char *port = "80"; const char *path = "/post"; const char *data = "name=Levi&age=30"; char request[1024]; snprintf(request, sizeof(request), "POST %s HTTP/1.1\r\n" "Host: %s\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: %zu\r\n" "Connection: close\r\n" "\r\n" "%s", path, host, strlen(data), data); send_request(host, port, request); } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s get|post\n", argv[0]); return 1; } if (strcmp(argv[1], "get") == 0) { http_get(); } else if (strcmp(argv[1], "post") == 0) { http_post(); } else { fprintf(stderr, "Unknown command: %s\n", argv[1]); return 1; } return 0; }