Асинхронный веб-сервер 001
Добавлено: 07 ноя 2024, 17:03
server_http_class-001.cpp
Компиляция:
Код: Выделить всё
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <mutex>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <cstdlib>
#define PORT 8090
#define BACKLOG 10
#define BUFFER_SIZE 1024
class HttpServer {
public:
void start();
private:
void listenForConnections();
void handleClient(int clientSocket);
std::string processHttpRequest(const std::string& request);
std::string createRedirectResponse(const std::string& host);
};
// start() Основная точка входа для запуска сервера.
void HttpServer::start() {
listenForConnections();
}
// listenForConnections() Метод для прослушивания соединений и передачи их на обработку.
void HttpServer::listenForConnections() {
int serverFd;
struct sockaddr_in address;
int opt = 1;
int addrLen = sizeof(address);
if ((serverFd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("Set socket options failed");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(serverFd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
if (listen(serverFd, BACKLOG) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
std::cout << "Server is listening on port " << PORT << std::endl;
while (true) {
int newSocket = accept(serverFd, (struct sockaddr *)&address, (socklen_t*)&addrLen);
if (newSocket < 0) {
perror("Accept failed");
continue;
}
// Передаем управление новым клиентом в отдельный поток
std::thread t(&HttpServer::handleClient, this, newSocket);
t.detach();
}
}
// handleClient() Метод для обработки клиента в отдельном потоке.
void HttpServer::handleClient(int clientSocket) {
char buffer[BUFFER_SIZE];
ssize_t bytesRead = recv(clientSocket, buffer, BUFFER_SIZE, 0);
if (bytesRead <= 0) {
std::cerr << "Error reading from socket" << std::endl;
close(clientSocket);
return;
}
std::string request(buffer, bytesRead);
std::cout << "Received request:\n" << request << std::endl;
// Обрабатываем запрос
std::string response = processHttpRequest(request);
if (!response.empty()) {
send(clientSocket, response.c_str(), response.length(), 0);
} else {
// Если ответ пустой, отправляем ошибку
std::string errorResponse = "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n";
send(clientSocket, errorResponse.c_str(), errorResponse.length(), 0);
}
close(clientSocket); // Закрываем соединение
}
// processHttpRequest() Метод для обработки HTTP-запроса.
std::string HttpServer::processHttpRequest(const std::string& request) {
if (request.substr(0, 3) == "GET") {
size_t pos = request.find("Host:");
if (pos != std::string::npos) {
size_t endPos = request.find("\r\n", pos);
// if (endPos != std::string::npos) {
// std::string host = request.substr(pos + 6, endPos - pos - 6);
// return createRedirectResponse(host);
// }
}
}
// Здесь можно добавить обработку других типов запросов (POST, PUT и т.д.)
return "";
}
// createRedirectResponse() Метод для создания ответа о перенаправлении на HTTPS.
std::string HttpServer::createRedirectResponse(const std::string& host) {
return "HTTP/1.1 301 Moved Permanently\r\n"
"Location: http://" + host + "\r\n"
"Connection: close\r\n"
"\r\n";
}
// Запуск сервера
int main() {
HttpServer server;
server.start();
return 0;
}
Код: Выделить всё
g++ -std=c++11 -o server_http_class-001 server_http_class-001.cpp -pthread