Rust Concurrent Web Server with Threads
Rust Threads and Synchronization: Exercise-5 with Solution
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.
It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.
https://www.w3resource.com/rust/threads_and_synchronization/rust-threads-and-synchronization-exercise-5.php
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics