Reputation: 67
So I am trying to better understand how a simple TCP server works within rust. Let's say that I have the simple TCP server below.
use std::io::Write;
use std::net::TcpListener;
use std::thread;
fn main() {
let listener = TcpListener::bind("127.0.0.1:9123").unwrap();
println!("listening started, ready to accept");
for stream in listener.incoming() {
thread::spawn(|| {
let mut stream = stream.unwrap();
stream.write(b"Hello World\r\n").unwrap();
});
}
}
The server works by accepting incoming connections from the socket given. Right after spawning the need thread, you redefine the stream variable so that you can change it to whatever you want. Then you can write to that variable whenever you want.
Let's then say that there is a client that looks like this:
use std::net::TcpStream;
//and any other imports that you need
fn main() {
let stream = TcpStream::connect("127.0.0.1:9123").unwrap();
//Then assume that you can read and write things back to the server
What I don't understand is how the thread handles the sever every time that there is a connection made. Is it like setting up multiple servers? How do you handle the packets that are going in and out of the server? How do you handle dropped connections?
Upvotes: 4
Views: 11970
Reputation: 16920
This is the typical multithreaded TCP server architecture.
accept()
each new connection (the loop on .incoming()
here),.incoming()
yields a new element), we start a new thread that will be responsible for all the dialogue happening on this specific connection,accept()
any potential new connection (the next iteration on .incoming()
) even if the previous thread spends a very long time in its dialogue with the client.At any time, the number of threads is number of connected clients + 1 (the +1 is the implicit main thread which is dedicated to accepting new connections).
Dealing with disconnections is the concern of each individual thread (regarding the only connection it handles).
This TCP server architecture is absolutely not specific to Rust.
Rust just encapsulates the underlying system calls (socket()
, bind()
, listen()
, accept()
...) in a nice API.
Upvotes: 7