140 lines
3.8 KiB
C
140 lines
3.8 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
#ifdef _WIN32
|
||
#include <winsock2.h>
|
||
#include <windows.h>
|
||
#else
|
||
#include <unistd.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/in.h>
|
||
#include <arpa/inet.h>
|
||
#endif
|
||
|
||
#define PORT 8080
|
||
#define BUFFER_SIZE 1024
|
||
#define HTML_FILE "index.html"
|
||
|
||
int main() {
|
||
#ifdef _WIN32
|
||
WSADATA wsaData;
|
||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||
perror("WSAStartup failed");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
SetConsoleOutputCP(CP_UTF8);
|
||
#endif
|
||
|
||
int server_fd, new_socket;
|
||
struct sockaddr_in address;
|
||
int addrlen = sizeof(address);
|
||
char buffer[BUFFER_SIZE] = {0};
|
||
|
||
printf("Hello World!\n");
|
||
// 创建socket文件描述符
|
||
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
|
||
perror("socket failed");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
|
||
// 设置socket选项,允许地址重用
|
||
int opt = 1;
|
||
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR,
|
||
(const char *)&opt, sizeof(opt))) {
|
||
perror("setsockopt");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
|
||
// 配置服务器地址结构
|
||
address.sin_family = AF_INET;
|
||
address.sin_addr.s_addr = INADDR_ANY;
|
||
address.sin_port = htons(PORT);
|
||
|
||
// 绑定socket到指定地址和端口
|
||
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
|
||
perror("bind failed");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
|
||
// 开始监听连接
|
||
if (listen(server_fd, 3) < 0) {
|
||
perror("listen");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
|
||
printf("HTTP服务器正在监听 %d 端口...\n", PORT);
|
||
|
||
while(1) {
|
||
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
|
||
&addrlen)) < 0) {
|
||
perror("accept");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
|
||
int valread = recv(new_socket, buffer, BUFFER_SIZE, 0);
|
||
printf("收到请求:\n%s\n", buffer);
|
||
|
||
FILE *html_file = fopen(HTML_FILE, "rb");
|
||
if (!html_file) {
|
||
const char *error_response =
|
||
"HTTP/1.1 404 Not Found\r\n"
|
||
"Content-Type: text/html; charset=utf-8\r\n"
|
||
"Connection: close\r\n"
|
||
"\r\n"
|
||
"<html><body><h1>404 - 文件未找到</h1></body></html>";
|
||
send(new_socket, error_response, strlen(error_response), 0);
|
||
closesocket(new_socket);
|
||
continue;
|
||
}
|
||
|
||
fseek(html_file, 0, SEEK_END);
|
||
long file_size = ftell(html_file);
|
||
fseek(html_file, 0, SEEK_SET);
|
||
|
||
char *html_content = (char *)malloc(file_size + 1);
|
||
if (!html_content) {
|
||
fclose(html_file);
|
||
const char *error_response =
|
||
"HTTP/1.1 500 Internal Server Error\r\n"
|
||
"Content-Type: text/html; charset=utf-8\r\n"
|
||
"Connection: close\r\n"
|
||
"\r\n"
|
||
"<html><body><h1>500 - 服务器错误</h1></body></html>";
|
||
send(new_socket, error_response, strlen(error_response), 0);
|
||
closesocket(new_socket);
|
||
continue;
|
||
}
|
||
|
||
fread(html_content, 1, file_size, html_file);
|
||
html_content[file_size] = '\0';
|
||
fclose(html_file);
|
||
|
||
char header[512];
|
||
sprintf(header,
|
||
"HTTP/1.1 200 OK\r\n"
|
||
"Content-Type: text/html; charset=utf-8\r\n"
|
||
"Content-Length: %ld\r\n"
|
||
"Connection: close\r\n"
|
||
"\r\n", file_size);
|
||
|
||
send(new_socket, header, strlen(header), 0);
|
||
send(new_socket, html_content, file_size, 0);
|
||
|
||
free(html_content);
|
||
|
||
printf("响应已发送\n");
|
||
|
||
#ifdef _WIN32
|
||
closesocket(new_socket);
|
||
#else
|
||
close(new_socket);
|
||
#endif
|
||
}
|
||
|
||
#ifdef _WIN32
|
||
WSACleanup();
|
||
#endif
|
||
|
||
return 0;
|
||
} |