#include #include #include #include #include #include #include // For std::thread #include // For std::chrono::seconds #include // For std::ifstream void handle_connection(int socket_fd) { char buffer[4096]; // Buffer to store request data ssize_t bytes_read; // Read the request data until there's none left or buffer is full std::string request; do { bytes_read = read(socket_fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; // Null-terminate what we have read and add to the request string request.append(buffer); // Check if we've received the end of the headers if (request.find("\r\n\r\n") != std::string::npos) { break; } } } while (bytes_read > 0); // Check for read error if (bytes_read == -1) { std::cerr << "Error reading request data." << std::endl; close(socket_fd); return; } std::cout << "Received HTTP request:\n" << request << std::endl; // Now prepare and send the HTTP response const char* response_body = "Hello, World!\n"; //There is a fixed HTTP repsonse that is under 128 bytes char http_response[128]; int body_length = strlen(response_body); int response_length = snprintf(http_response, sizeof(http_response), "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Connection: close\r\n" "Content-Length: %d\r\n" // Include the Content-Length header "\r\n" "%s", body_length, response_body); if (response_length >= 0) { // Ensure the response is correctly sized if there was a potential overflow write(socket_fd, http_response, (size_t)response_length > sizeof(http_response) ? sizeof(http_response) : (size_t)response_length); std::cout << "Sent HTTP response.\n"; } else { std::cerr << "Error preparing HTTP response." << std::endl; } buffer[0] = '\0'; // Clear the buffer after processing request close(socket_fd); } void serve_file_content(int socket_fd) { std::ifstream file("yourfile.txt"); // Open your premade file std::string word; while (file >> word) { // Output one word at a time with a 1-second delay std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << word << std::endl; // Here, you would also write the word to the HTTP response if needed } } int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); // There are a lot of Unix related specifics that I am not familiar with // I used the following code as a reference for the socket setup if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); 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); } std::cout << "Listening on port 8080...\n"; while (true) { std::cout << "Waiting for connections...\n"; // System is blocking until a connection is made if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } //When a new connection is made, handle the connection handle_connection(new_socket); } return 0; }