TCP networking
| Bind a listener | |
| Accept loop | |
| Read the request | |
| Write a response |
Bind a listener
A TcpListener waits for TCP connections on an address you choose. The bind call may fail when the port is busy, so unwrap during learning and handle errors later:
use std::net::TcpListener;
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
println!("listening on 7878");
}
Binding to 127.0.0.1 keeps the server on your own machine. If you want the operating system view of sockets first, read the sockets background in C, then come back here for the Rust version.
Accept loop
The incoming method yields one stream per connection, forever. Match on each item so one bad handshake never kills the server:
use std::net::TcpListener;
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
for conn in listener.incoming() {
match conn {
Ok(_) => println!("new connection"),
Err(e) => eprintln!("accept failed: {}", e),
}
}
}
Read the request
Reading starts with accept, which returns the stream directly for a single client. Fill a byte buffer and note how many bytes arrived:
use std::io::Read;
use std::net::TcpListener;
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
let (mut stream, _) = listener.accept().unwrap();
let mut buf = [0; 512];
let n = stream.read(&mut buf).unwrap();
println!("read {} bytes", n);
}
TCP is a stream, so one read may hold half a request. Capstones keep reads tiny and parse only what they need.
Write a response
Answers go back with write_all, which keeps sending until every byte leaves. A hand-built HTTP reply is just headers, a blank line, and a body:
use std::io::Write;
use std::net::TcpListener;
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
let (mut stream, _) = listener.accept().unwrap();
let body = "hi";
let reply = format!("HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", body.len(), body);
stream.write_all(reply.as_bytes()).unwrap();
}
Point a browser at the address and the word hi appears. The next two lessons grow these short programs into finished projects.
Next: Capstone: wordfreq CLI
Article author: Arthur Isaev