yycbiajixixi 2023-05-27 18:09 采纳率: 50%
浏览 17

linux代理服务器搭建

你好,这是我自己写的Linux代理服务器,在虚拟机centos7中运行时,我用telnet命令来测试,输入一个GET请求,结果只能访问百度这个网站,其它的返回的都是404错误,只有百度是200 ok。
请问这是什么原因啊?感谢


#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 <sys/types.h>
#include <sys/wait.h>
#include <netdb.h> 
#include "proxy_parse.h"
#define MAX_CONNECTIONS 100

void handle_client_request(int client_socket) {
    // 读取客户端请求数据
    char buffer[4096];
    ssize_t num_bytes = recv(client_socket, buffer, sizeof(buffer) - 1, 0);
    
    if (num_bytes <= 0) {
        perror("Failed to read client request");
        goto cleanup; 
    }

    // 解析HTTP请求,调用解析库的函数
    ParsedRequest* parsed_request = malloc(sizeof(ParsedRequest));
    ParsedHeader* parsed_headers[10];
    int num_headers = 0;
    
    int parse_result = parse_request_header(buffer, parsed_request, parsed_headers, &num_headers);

    if (parse_result) {
        // 打印HTTP请求信息
        printf("Method: %s\n", parsed_request->method);
        printf("URL: %s\n", parsed_request->url);
        printf("Host: %s\n", parsed_request->host);
        printf("Port: %d\n", parsed_request->port);
        printf("Http-version: %s\n", parsed_request->http_version);
        printf("\nHeaders:\n");
        int i;
        for (i = 0; i < num_headers; i++) {
            printf("%s:%s\n", parsed_headers[i]->key, parsed_headers[i]->value);
        }

        struct addrinfo hints, *host_info;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        
        // host_info返回查询到的地址信息 
        if (getaddrinfo(parsed_request->host, NULL, &hints, &host_info) != 0) {
            perror("Failed to get IP address");
            goto cleanup;
        }
        
        struct sockaddr_in target_address;
        memset(&target_address, 0, sizeof(target_address));
        target_address.sin_family = AF_INET;
        target_address.sin_addr.s_addr = ((struct sockaddr_in*)(host_info->ai_addr))->sin_addr.s_addr;
        target_address.sin_port = htons(parsed_request->port);
        
        // 目标服务器
        int target_socket = socket(AF_INET, SOCK_STREAM, 0);
        if (target_socket == -1) {
            perror("Failed to create socket");
            goto cleanup;
        }
        
        // 连接到目标服务器
        if (connect(target_socket, (struct sockaddr*)&target_address, sizeof(target_address)) == -1) {
            perror("Failed to connect to target server");
            goto cleanup;
        }

        printf("成功连接到目标服务器\n");
        char response[4096];
        snprintf(response, sizeof(response), "%s %s HTTP/%s\r\nHost: %s\r\nConnection: close\r\n\r\n",parsed_request->method, parsed_request->url,parsed_request->http_version, parsed_request->host);
        printf("%s\n",response); 
        // 将客户端请求转发给目标服务器
        if (send(target_socket, response, strlen(response), 0) == -1) {
            perror("Failed to send client request to target server");
            goto cleanup;
        }
        printf("成功将客户请求转发到目标服务器\n");
        // 从目标服务器接收响应并将响应返回给客户端
        while (1) {
            num_bytes = recv(target_socket, buffer, sizeof(buffer) - 1, 0);
            if (num_bytes <= 0) {
                break;
            }
            printf("成功从目标服务器接收到响应\n");
            if (send(client_socket, buffer, num_bytes, 0) == -1){
                perror("Failed to send response to client");
                goto cleanup;
            }
            printf("成功将响应发送给客户端\n");
        }
        
        cleanup:
        // 释放资源
        close(target_socket);
        free_parsed_request(parsed_request);
        free_parsed_headers(parsed_headers, num_headers);
    } else {
       printf("Failed to parse request\n");
       char request_buffer[4096];
        snprintf(request_buffer,sizeof(request_buffer),"未实现\n");
       if(send(client_socket,request_buffer,strlen(request_buffer),0)==-1){
           perror("Failed to send response to client");
        goto cleanup;
       }
       close(client_socket);
       goto cleanup;
    }

    // 关闭客户端连接
    close(client_socket);
}

int main(int argc, char* argv[]){
    int port;
    if(argc < 2){
        printf("传入参数端口号\n");
        return 1;
    }
    
    port=atoi(argc[1]);

    int server_socket;
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0){
        perror("Failed to create server socket");
        exit(1);
    }
    
    // 设置代理服务器地址
    struct sockaddr_in server_address;
    memset(&server_address, 0, sizeof(server_address));
    server_address.sin_family = AF_INET;
    
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(port);
    
    // 绑定套接字到指定地址和端口
    if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
        perror("Failed to bind server socket");
        return 1;
    }

    // 开始监听传入的连接
    if (listen(server_socket, MAX_CONNECTIONS) < 0) {
        perror("Failed to listen for connections");
        return 1;
    }

    printf("Proxy server started on port %d\n", port);
    
    while (1) {
        // 等待传入的客户端连接
        struct sockaddr_in client_address;
        socklen_t client_address_length = sizeof(client_address);
        int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_length);
      
        if (client_socket < 0) {
            perror("Failed to accept client connection");
            continue;
        }

        // 使用fork()生成新进程来处理客户端请求
        pid_t child_pid = fork();
        
        if (child_pid < 0) {
            perror("Failed to create child process");
            close(client_socket);
            continue;
        } else if (child_pid == 0) {
            // 子进程处理客户端请求
            close(server_socket);
            handle_client_request(client_socket);
            exit(0);
        } else {
            // 父进程继续等待下一个客户端连接
            close(client_socket);
            // 等待子进程结束,避免产生僵尸进程
            waitpid(child_pid, NULL, 0);
        }
    }

    // 关闭服务器套接字
    close(server_socket);

    return 0;
}

  • 写回答

2条回答 默认 最新

报告相同问题?

问题事件

  • 创建了问题 5月27日

悬赏问题

  • ¥15 WPF动态创建页面内容
  • ¥15 如何对TBSS的结果进行统计学的分析已完成置换检验,如何在最终的TBSS输出结果提取除具体值及如何做进一步相关性分析
  • ¥15 SQL数据库操作问题
  • ¥100 关于lm339比较电路出现的问题
  • ¥15 Matlab安装yalmip和cplex功能安装失败
  • ¥15 加装宝马安卓中控改变开机画面
  • ¥15 STK安装问题问问大家,这种情况应该怎么办
  • ¥15 关于罗技鼠标宏lua文件的问题
  • ¥15 halcon ocr mlp 识别问题
  • ¥15 已知曲线满足正余弦函数,根据其峰值,还原出整条曲线