如上述要求一样提供文件注释和函数注释,保留源文件中的函数注释(注意不能用//),全英文注释,将其中打印的中文信息也翻译成英文#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/sendfile.h>
#include <libgen.h>
#include <sys/stat.h>
#include <ctype.h>
#include <netinet/in.h>
#include "utils.h"
#include "http_parser.h"
#define MAX_CLIENTS 1024
// 接受新连接
void accept_new_connection(int server_fd, fd_set *read_fds, int *max_fd)
{
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
if (client_fd < 0)
{
log_message(LOG_ERROR, "accept失败: %s", strerror(errno));
return;
}
// 获取客户端IP和端口
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip));
int client_port = ntohs(client_addr.sin_port);
if (client_fd >= MAX_CLIENTS)
{
log_message(LOG_WARN, "客户端 %s:%d 超出最大连接数限制 (fd=%d)",
client_ip, client_port, client_fd);
dprintf(client_fd, "HTTP/1.1 503 Service Unavailable\r\n\r\n");
close(client_fd);
return;
}
FD_SET(client_fd, read_fds);
if (client_fd > *max_fd)
*max_fd = client_fd;
log_message(LOG_INFO, "接受来自 %s:%d 的新连接 (fd=%d)",
client_ip, client_port, client_fd);
}
// 读取客户端请求
void handle_client(int client_fd, fd_set *read_fds)
{
char buffer[BUFFER_SIZE] = {0};
ssize_t bytes_read = read(client_fd, buffer, sizeof(buffer) - 1);
if (bytes_read <= 0)
{
if (bytes_read == 0)
{
log_message(LOG_INFO, "客户端 fd=%d 断开连接", client_fd);
}
else
{
log_message(LOG_ERROR, "读取客户端 fd=%d 失败: %s",
client_fd, strerror(errno));
}
FD_CLR(client_fd, read_fds);
close(client_fd);
return;
}
buffer[bytes_read] = '\0';
log_message(LOG_DEBUG, "收到来自 fd=%d 的请求:\n%.*s",
client_fd, (int)bytes_read, buffer);
http_request req;
if (parse_http_request(buffer, &req) < 0)
{
log_message(LOG_WARN, "解析 fd=%d 的HTTP请求失败", client_fd);
dprintf(client_fd, "HTTP/1.1 400 Bad Request\r\n\r\n");
FD_CLR(client_fd, read_fds);
close(client_fd);
return;
}
log_message(LOG_INFO, "处理 fd=%d 的 %s 请求: %s",
client_fd, req.method, req.path);
if (strcasecmp(req.method, "GET") == 0)
{
log_message(LOG_DEBUG, "处理 fd=%d 的GET请求", client_fd);
process_request(&req, client_fd);
}
else if (strcasecmp(req.method, "POST") == 0)
{
if (strcmp(req.path, "/data/contact.json") == 0)
{
log_message(LOG_DEBUG, "处理 fd=%d 的联系表单提交", client_fd);
handle_contact_form(&req, client_fd);
}
else
{
log_message(LOG_WARN, "fd=%d 的不支持POST路径: %s",
client_fd, req.path);
dprintf(client_fd, "HTTP/1.1 405 Method Not Allowed\r\n\r\n");
}
}
else
{
log_message(LOG_WARN, "fd=%d 的不支持HTTP方法: %s",
client_fd, req.method);
dprintf(client_fd, "HTTP/1.1 405 Method Not Allowed\r\n\r\n");
}
FD_CLR(client_fd, read_fds);
close(client_fd);
log_message(LOG_DEBUG, "完成处理 fd=%d 的请求", client_fd);
}
int main(int argc, char *argv[])
{
int port = 80; // 默认端口
// 初始化日志系统
init_logger(argv[0]);
log_message(LOG_INFO, "Starting server on port %d", port);
// 处理命令行参数
if (argc >= 2)
{
char *endptr;
long input_port = strtol(argv[1], &endptr, 10);
if (*endptr != '\0' || input_port < 1 || input_port > 65535)
{
log_message(LOG_WARN, "无效端口号 '%s',使用默认端口80", argv[1]);
}
else
{
port = (int)input_port;
}
}
log_message(LOG_INFO, "使用端口: %d", port);
int server_fd = create_listen_socket(port);
if (server_fd < 0)
{
log_message(LOG_ERROR, "创建监听socket失败");
return EXIT_FAILURE;
}
log_message(LOG_INFO, "监听socket创建成功,fd=%d", server_fd);
fd_set read_fds;
int max_fd = server_fd;
struct timeval timeout;
log_message(LOG_INFO, "Web服务器在端口 %d 启动", port);
while (1)
{
FD_ZERO(&read_fds);
FD_SET(server_fd, &read_fds);
// 设置超时时间为5秒
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int activity = select(max_fd + 1, &read_fds, NULL, NULL, &timeout);
if (activity < 0)
{
if (errno == EINTR)
{
log_message(LOG_DEBUG, "select被信号中断");
continue;
}
log_message(LOG_ERROR, "select失败: %s", strerror(errno));
break;
}
else if (activity == 0)
{
// 超时,无活动连接
log_message(LOG_DEBUG, "select超时,无活动连接");
continue;
}
// 检查服务器socket是否有新连接
if (FD_ISSET(server_fd, &read_fds))
{
accept_new_connection(server_fd, &read_fds, &max_fd);
}
// 检查客户端socket是否有数据
for (int i = 0; i <= max_fd; i++)
{
if (i != server_fd && FD_ISSET(i, &read_fds))
{
handle_client(i, &read_fds);
}
}
}
close(server_fd);
log_message(LOG_INFO, "服务器关闭");
close_logger();
return 0;
}
最新发布