一个简单的基于C语言的HTTP代理服务器的案例

一个简单的基于C语言的HTTP代理服务器的案例。这个代理服务器可以接收客户端的HTTP请求,并将请求转发到目标服务器,然后将服务器的响应返回给客户端。

1. 代理服务器的主要代码

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BUFFER_SIZE 1024

// 函数声明
void handle_client_request(int client_socket);
void forward_request(int client_socket, char *server_response);

int main(int argc, char *argv[]) {
    int server_fd, client_fd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len = sizeof(client_addr);

    // 创建套接字
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(8080); // 监听8080端口

    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Socket bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听连接
    listen(server_fd, 5);

    printf("HTTP Proxy Server listening on port 8080\n");

    while (1) {
        client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
        if (client_fd < 0) {
            perror("Accept failed");
            continue;
        }

        // 处理客户端请求
        handle_client_request(client_fd);
        close(client_fd);
    }

    close(server_fd);
    return 0;
}

void handle_client_request(int client_socket) {
    char buffer[BUFFER_SIZE];
    int read_size;

    // 读取客户端请求
    read_size = read(client_socket, buffer, BUFFER_SIZE);
    if (read_size < 0) {
        perror("Read failed");
        return;
    }

    // 打印请求(调试用)
    printf("Client Request:\n%s\n", buffer);

    // 解析请求并找到目标服务器地址
    char *host = strstr(buffer, "Host:") + 6;
    char *host_end = strstr(buffer, "\r\n");
    *host_end = '\0';
    host += strspn(host, " \t");

    // 目标服务器地址
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(80); // 默认HTTP端口

    // 将主机名转换为IP地址
    if (inet_pton(AF_INET, host, &server_addr.sin_addr) <= 0) {
        perror("Invalid host address");
        return;
    }

    // 连接到目标服务器
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Connect to server failed");
        return;
    }

    // 转发客户端请求到目标服务器
    write(server_socket, buffer, read_size);

    // 读取服务器响应并转发回客户端
    char server_buffer[BUFFER_SIZE];
    int server_read = read(server_socket, server_buffer, BUFFER_SIZE);
    write(client_socket, server_buffer, server_read);

    // 关闭服务器连接
    close(server_socket);
}

2. 说明

  1. 主函数:创建一个监听套接字,绑定到本地地址和端口(例如8080),然后监听客户端连接。
  2. handle_client_request函数:读取客户端的HTTP请求,解析请求中的主机名,然后将请求转发到目标服务器。
  3. forward_request函数:从目标服务器读取响应,并将响应转发回客户端(这个函数在示例中省略了,可以根据需要实现)。

3. 编译和运行

将上述代码保存为proxy_server.c,然后使用以下命令编译和运行:

sh 复制代码
gcc -o proxy_server proxy_server.c
./proxy_server

4. 测试代理服务器

你可以使用浏览器或curl来测试代理服务器。例如,使用curl:

sh 复制代码
curl -x http://localhost:8080 http://example.com

这将通过你的代理服务器访问http://example.com

5. 注意事项

  • 这个示例代码是一个基本的HTTP代理服务器,没有实现完整的HTTP协议支持,例如持久连接(keep-alive)和HTTP隧道(tunneling)。
  • 在实际应用中,你可能需要处理更多的HTTP请求方法(如POST、PUT等),并支持HTTPS代理。
  • 安全性和错误处理在实际应用中非常重要,需要进一步完善。

这个案例提供了一个简单的起点,你可以在此基础上扩展更多功能和改进。

相关推荐
2401_85893688几秒前
【Linux C 编程】标准 IO 详解与实战:从基础接口到文件操作实战
linux·c语言
迎仔3 分钟前
B-算力中心网络隔离的必要性:为什么必须隔离?
网络
野指针YZZ1 小时前
一键配置RK3588网络与SSH远程连接
网络·ssh·rk3588
迎仔1 小时前
10-网络安全监控与事件响应:数字世界的智能监控与应急系统
网络·安全·web安全
上海合宙LuatOS2 小时前
LuatOS核心库API——【audio 】
java·网络·单片机·嵌入式硬件·物联网·音视频·硬件工程
季明洵2 小时前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
深圳市恒星物联科技有限公司3 小时前
水质流量监测仪:复合指标监测的管网智能感知设备
大数据·网络·人工智能
浅念-3 小时前
C语言编译与链接全流程:从源码到可执行程序的幕后之旅
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
爱吃生蚝的于勒3 小时前
【Linux】进程信号之捕捉(三)
linux·运维·服务器·c语言·数据结构·c++·学习
The森3 小时前
Linux IO 模型纵深解析 01:从 Unix 传统到 Linux 内核的 IO 第一性原理
linux·服务器·c语言·经验分享·笔记·unix