-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhttp_server.cpp
121 lines (103 loc) · 3.5 KB
/
http_server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#define PORT 6666
#define BUFFER_SIZE 1024
int main() {
// 创建套接字
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == 0) {
perror("Socket creation failed");
return -1;
}
// 设置地址和端口
sockaddr_in address;
int addrlen = sizeof(address);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 绑定套接字到端口
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
close(server_fd);
return -1;
}
// 开始监听
if (listen(server_fd, 10) < 0) {
perror("Listen failed");
close(server_fd);
return -1;
}
// 设置非阻塞模式
int flags = fcntl(server_fd, F_GETFL, 0);
fcntl(server_fd, F_SETFL, flags | O_NONBLOCK);
std::cout << "HTTP server is running on port " << PORT << "...\n";
while (true) {
sockaddr_in client_address;
socklen_t client_addrlen = sizeof(client_address);
// 尝试接受客户端连接
int new_socket = accept(server_fd, (struct sockaddr *)&client_address, &client_addrlen);
if (new_socket < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// 如果没有连接,继续循环
usleep(100000); // 睡眠 100 毫秒
continue;
} else {
perror("Accept failed");
close(server_fd);
return -1;
}
}
// 设置客户端套接字为非阻塞模式
flags = fcntl(new_socket, F_GETFL, 0);
fcntl(new_socket, F_SETFL, flags | O_NONBLOCK);
char buffer[BUFFER_SIZE] = {0};
std::string request;
// 非阻塞读取请求数据
while (true) {
int bytes_read = read(new_socket, buffer, BUFFER_SIZE - 1);
if (bytes_read < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// 如果没有数据可读,稍后再试
usleep(100000); // 睡眠 100 毫秒
continue;
} else {
perror("Read failed");
close(new_socket);
break;
}
} else if (bytes_read == 0) {
// 客户端关闭连接
break;
} else {
buffer[bytes_read] = '\0';
request += buffer;
// 如果读取到完整请求,退出循环
if (request.find("\r\n\r\n") != std::string::npos) {
break;
}
}
}
if (!request.empty()) {
std::cout << "Received request:\n" << request << "\n";
// 构造 HTTP 响应
std::string response_header =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 13\r\n"
"\r\n";
std::string response_body = "Hello, World!";
send(new_socket, response_header.c_str(), response_header.size(), 0);
send(new_socket, response_body.c_str(), response_body.size(), 0);
}
// 关闭客户端连接
close(new_socket);
}
// 关闭服务器套接字
close(server_fd);
return 0;
}