c使用线程实现web代理服务器
时间: 2024-02-15 16:01:39 浏览: 19
以下是一个简单的使用线程实现Web代理服务器的C代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 4096
#define MAX_THREADS 10
struct thread_data {
int client_fd;
};
void *handle_request(void *arg) {
struct thread_data *data = (struct thread_data *) arg;
int client_fd = data->client_fd;
char buffer[BUFFER_SIZE];
ssize_t n;
// 接收客户端请求
n = recv(client_fd, buffer, BUFFER_SIZE, 0);
if (n < 0) {
perror("recv");
goto close_connection;
}
// 解析HTTP请求,获取URL
char *url = strstr(buffer, "GET ") + 4;
char *end = strstr(url, " HTTP/");
*end = '\0';
// 向目标服务器发起HTTP请求
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr = {
.sin_family = AF_INET,
.sin_port = htons(80),
.sin_addr.s_addr = inet_addr("目标服务器IP地址")
};
if (connect(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
perror("connect");
goto close_connection;
}
char request[BUFFER_SIZE];
sprintf(request, "GET %s HTTP/1.1\r\nHost: 目标服务器域名\r\n\r\n", url);
send(server_fd, request, strlen(request), 0);
// 接收目标服务器的HTTP响应,发送回客户端
while ((n = recv(server_fd, buffer, BUFFER_SIZE, 0)) > 0) {
send(client_fd, buffer, n, 0);
}
close_connection:
// 关闭连接,销毁线程
close(client_fd);
close(server_fd);
free(data);
pthread_exit(NULL);
}
int main() {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr = {
.sin_family = AF_INET,
.sin_port = htons(8080),
.sin_addr.s_addr = INADDR_ANY
};
if (bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 10) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
while (1) {
int client_fd = accept(server_fd, NULL, NULL);
if (client_fd < 0) {
perror("accept");
continue;
}
// 创建新线程处理客户端请求
pthread_t thread_id;
struct thread_data *data = malloc(sizeof(struct thread_data));
data->client_fd = client_fd;
if (pthread_create(&thread_id, NULL, handle_request, (void *) data) < 0) {
perror("pthread_create");
close(client_fd);
free(data);
}
// 控制线程数量,避免过多线程创建和销毁操作
while (pthread_active_count() > MAX_THREADS) {
sleep(1);
}
}
return 0;
}
```
该代码使用了POSIX线程库pthread,实现了一个简单的Web代理服务器。主线程使用accept函数接受客户端请求,每个新请求都会创建一个新的线程来处理。在处理线程中,使用recv函数接收客户端请求,解析HTTP请求,向目标服务器发起HTTP请求,接收目标服务器的HTTP响应,然后将响应发送回客户端。最后关闭连接,销毁线程。
该代码还使用了线程池技术,控制线程数量,避免过多线程创建和销毁操作,提高了效率。