你好,这是我自己写的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;
}
如果排除是防火墙问题的话,建议你看一下代理服务器在转发请求时,解析目标服务器的主机名获取的IP地址。
如果DNS解析失败,可能无法连接到目标服务器。你可以尝试在代码中添加一些调试语句,打印出解析到的IP地址,以确认是否正确解析了目标服务器的主机名。