Rust Concurrent Web Server with Threads
Write a Rust program that simulates a simple concurrent web server using threads.
Sample Solution:
Rust Code:
use std::net::{TcpListener, TcpStream}; // Import necessary networking modules
use std::io::{Read, Write}; // Import modules for reading from and writing to streams
use std::thread; // Import module for creating threads
// Define a function to handle each client connection
fn handle_client(mut stream: TcpStream) {
let mut buffer = [0; 512]; // Create a buffer to store incoming data
// Read data from the stream into the buffer
stream.read(&mut buffer).unwrap();
// Convert the data to a string
let request = String::from_utf8_lossy(&buffer[..]);
// Print the received request
println!("Received request: {}", request);
// Define a simple HTTP response
let response = "HTTP/1.1 200 OK\r\n\r\nHello, World!";
// Write the response back to the client
stream.write(response.as_bytes()).unwrap();
// Flush the stream to ensure all data is sent
stream.flush().unwrap();
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").unwrap(); // Create a TCP listener on localhost port 8080
println!("Server listening on port 8080...");
// Accept incoming connections and handle them concurrently using threads
for stream in listener.incoming() {
match stream {
Ok(stream) => {
// Spawn a new thread to handle each client connection
thread::spawn(move || {
handle_client(stream); // Call the handle_client function for each client
});
}
Err(e) => {
// Print an error message if there's an issue accepting a connection
println!("Error accepting connection: {}", e);
}
}
}
}
Output:
Server listening on port 8080...
Explanation:
In the exercise above,
- Import the necessary modules from the standard library (std::net, std::io, and std::thread) for handling networking, input/output operations, and concurrency with threads.
- Next, we define a function called "handle_client()", which takes a 'TcpStream' representing a client connection. Inside this function, we read data from the stream, print the received request, construct a simple HTTP response, and write the response back to the client.
- In the main function, we create a TCP listener bound to 127.0.0.1:8080, which means it listens for incoming connections on localhost at port 8080.
- We print a message indicating that the server is listening on port 8080.
- We enter a loop where we continuously accept incoming connections using the listener.incoming() method. This method returns an iterator of incoming connections represented as Result<TcpStream, std::io::Error>.
- Inside the loop, for each incoming connection, we spawn a new thread using thread::spawn. This allows us to handle multiple connections concurrently. We pass the incoming 'TcpStream' to the "handle_client()" function in the spawned thread.
- If there's an error accepting a connection, we print an error message.
Rust Code Editor:
Previous: Rust Program: Matrix Multiplication with Parallel Threads.
Next: Rust Concurrent Task Scheduler with Threads.
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics