Files

113 lines
2.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define BUF_SIZE 4096
#define BODY_BUF 2048
// 域名转IP
static int domain_to_ip(const char *domain, char *ip_buf) {
struct hostent *host = gethostbyname(domain);
if (!host) return -1;
struct in_addr **addr_list = (struct in_addr **)host->h_addr_list;
strcpy(ip_buf, inet_ntoa(*addr_list[0]));
return 0;
}
// 从 HTTP 完整响应中提取正文(跳过头部)
void extract_http_body(const char *response, char *body) {
const char *split = "\r\n\r\n";
char *pos = strstr(response, split);
if (pos) {
strcpy(body, pos + 4); // 跳过 \r\n\r\n
} else {
strcpy(body, "parse error");
}
}
// HTTP GET,返回完整响应字符串
int http_get(const char *host, const char *path, int port, char *response) {
int sock;
struct sockaddr_in addr;
char ip[64], req[512];
int total_len = 0;
if (domain_to_ip(host, ip) < 0) return -1;
sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(sock);
return -2;
}
snprintf(req, sizeof(req),
"GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n\r\n",
path, host);
send(sock, req, strlen(req), 0);
// 接收完整数据
while (1) {
int len = recv(sock, response + total_len, BUF_SIZE - 1 - total_len, 0);
if (len <= 0) break;
total_len += len;
}
response[total_len] = 0;
close(sock);
return total_len;
}
// HTTP POST
int http_post(const char *host, const char *path, int port, const char *data, int data_len, char *response) {
int sock;
struct sockaddr_in addr;
char ip[64], req[1024];
int total_len = 0;
if (domain_to_ip(host, ip) < 0) return -1;
sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(sock);
return -2;
}
snprintf(req, sizeof(req),
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: %d\r\n"
"Connection: close\r\n\r\n%s",
path, host, data_len, data);
send(sock, req, strlen(req), 0);
while (1) {
int len = recv(sock, response + total_len, BUF_SIZE - 1 - total_len, 0);
if (len <= 0) break;
total_len += len;
}
response[total_len] = 0;
close(sock);
return total_len;
}