TCP listener
- Rust course
- Advanced
- Lesson 25/81
- 6 min
Accept clients in a loop with TcpListener.
Chat server: TCP listener
In this project we'll build a chat server where several clients connect and exchange messages. The first step is accepting connections: TcpListener::bind listens on an address, accept waits until a client connects and returns a TcpStream:
use std::net::TcpListener;
let dinleyici = TcpListener::bind("127.0.0.1:7878")?;
for baglanti in dinleyici.incoming() {
let akis = baglanti?;
println!("bağlandı: {}", akis.peer_addr()?);
}If port 0 is given, the operating system picks a free port; you learn which with local_addr(). It's handy for tests.
Reading and writing
TcpStream implements both Read and Write. In a line-based protocol, BufReader::read_line is used for reading and writeln! for writing:
use std::io::{BufRead, BufReader, Write};
use std::net::TcpStream;
let mut istemci = TcpStream::connect(adres)?;
writeln!(istemci, "merhaba")?;
let (akis, _) = dinleyici.accept()?;
let mut satir = String::new();
BufReader::new(akis).read_line(&mut satir)?;Practice First connection
Listen on 127.0.0.1:0 and get the address with local_addr(). Let a thread connect to that address and write the line merhaba. Let the main thread take the connection with accept, read the line and print alındı: merhaba.
Starter code
use std::io::{self, BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;
fn main() {
// buraya yaz
}Sample solution
use std::io::{self, BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;
fn main() -> io::Result<()> {
let dinleyici = TcpListener::bind("127.0.0.1:0")?;
let adres = dinleyici.local_addr()?;
let istemci = thread::spawn(move || -> io::Result<()> {
let mut akis = TcpStream::connect(adres)?;
writeln!(akis, "merhaba")?;
Ok(())
});
let (akis, _) = dinleyici.accept()?;
let mut s = String::new();
BufReader::new(akis).read_line(&mut s)?;
println!("alındı: {}", s.trim());
istemci.join().unwrap()?;
Ok(())
}Expected output
alındı: merhaba
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 When does the <code>incoming()</code> loop end?
- Never; the server keeps waiting for new connections Correct answer
- After the first connection
- When there are no connections left
- After a second
Explanation: .take(n) can be used for a fixed number of connections; in tests this makes the loop end.
2 Accept a connection
let (akis, adres) = dinleyici.____()?;
let (akis, adres) = dinleyici.accept()?;
Explanation: accept waits until a client connects.
3 Function and role
| Term | Meaning |
|---|---|
TcpListener::bind |
Listens on an address |
accept() |
Waits for a connection |
TcpStream::connect |
Connects to a server |
local_addr() |
Actual port |