最近通过 rust book 学习 rust,根据最后一章的内容制作了一个简单的异步 http 服务器。
项目结构
|-- hanabi
|-- .gitignore
|-- 404.html
|-- Cargo.lock
|-- Cargo.toml
|-- hello.html
|-- src
|-- lib.rs
|-- main.rs
|-- target
|-- ..
代码部分
main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14
fnmain() { // returns a TcpListener instance(wrapped by Result<T,E>) let listener = TcpListener::bind("127.0.0.1:8080").unwrap(); let pool = ThreadPool::new(4); // iterate to fetch the incoming tcp connection // store the tcp connection inside stream // it's currently synchronized. for stream in listener.incoming() { let stream = stream.unwrap(); pool.execute(|| { handle_connection(stream); }); } }
main函数部分,我们设计了一个ThreadPool来实现同步地接受多个请求,在每次接受到一个listener.incoming()的请求时,都把他转化为一个stream后在 pool 里进行execute,handle方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
fnhandle_connection(mut stream: TcpStream) { letmut buffer = [0; 1024]; stream.read(&mut buffer).unwrap(); let (get, sleep) = (b"GET / HTTP/1.1\r\n", b"GET /sleep HTTP/1.1\r\n"); let (filename, status_line) = if buffer.starts_with(get) { ("hello.html", "HTTP/1.1 200 OK\r\n\r\n") } elseif buffer.starts_with(sleep) { thread::sleep(Duration::from_millis(10000)); ("hello.html", "HTTP/1.1 200 OK\r\n\r\n") } else { ("404.html", "HTTP/1.1 404 NOT FOUND\r\n\r\n") }; let body = fs::read_to_string(filename).unwrap(); let response = format!("{}{}", status_line, body); stream.write(response.as_bytes()).unwrap(); stream.flush().unwrap(); }