linux c 多线程http服务器
时间: 2023-12-27 15:04:09 浏览: 79
以下是一个简单的基于 Linux C 多线程的 HTTP 服务器示例,使用了 POSIX 线程库和 socket 编程接口:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
#define MAX_CONNECTIONS 10
#define BUFFER_SIZE 1024
void *handle_connection(void *arg) {
int conn_fd = *(int*)arg;
char buffer[BUFFER_SIZE];
ssize_t n;
memset(buffer, 0, sizeof(buffer));
n = read(conn_fd, buffer, sizeof(buffer)-1);
if (n <= 0) {
close(conn_fd);
pthread_exit(NULL);
}
char *response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\nHello, world!";
write(conn_fd, response, strlen(response));
close(conn_fd);
pthread_exit(NULL);
}
int main() {
int sock_fd, conn_fd;
struct sockaddr_in serv_addr, client_addr;
socklen_t client_len;
pthread_t threads[MAX_CONNECTIONS];
// create socket
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
perror("Failed to create socket");
exit(EXIT_FAILURE);
}
// set server address
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
// bind socket to server address
if (bind(sock_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Failed to bind socket");
exit(EXIT_FAILURE);
}
// listen for connections
if (listen(sock_fd, MAX_CONNECTIONS) < 0) {
perror("Failed to listen for connections");
exit(EXIT_FAILURE);
}
printf("HTTP server is listening on port %d\n", PORT);
// handle connections in separate threads
while (1) {
client_len = sizeof(client_addr);
conn_fd = accept(sock_fd, (struct sockaddr*)&client_addr, &client_len);
if (conn_fd < 0) {
perror("Failed to accept connection");
continue;
}
pthread_t thread;
if (pthread_create(&thread, NULL, handle_connection, &conn_fd) < 0) {
perror("Failed to create thread");
close(conn_fd);
continue;
}
pthread_detach(thread);
}
return 0;
}
```
上述代码创建了一个监听在 8080 端口的 HTTP 服务器,可以处理多个连接。在每个连接到来时,都会创建一个新的线程来处理请求。在处理请求的线程中,首先读取请求消息,然后发送一个简单的响应消息。
需要注意的是,在多线程环境下,需要使用线程安全的函数和数据结构,以避免竞争条件和死锁。例如,在本例中,每个线程都需要使用不同的连接套接字(conn_fd),因此需要将套接字的值作为线程参数传递,而不是直接使用全局变量。同时,需要注意在每个线程中关闭连接套接字,以避免资源泄漏。
阅读全文