νμ€ν¬
Rustμ νμ€ν¬(μμ ) μμ€ν μ κ²½λ μ€λ λ©μ ν μ’ λ₯λ‘ λ³Ό μ μμ΅λλ€.
νλμ μμ
μλ, μ€νμκ° μ΄ μμ
μ μ§ννκΈ° μν΄ κ³μ ν΄λ§νλ, μ΅μμ futureκ° ν κ° μμ΅λλ€. μ΄ futureμλ poll
λ©μλκ° ν΄λ§νλ μ€μ²©λ futureκ° ν κ° μ΄μ μμ μ μμ΅λλ€. μ΄λ¬ν μ€μ²©λ futureλ μΌλ°μ μΈ ν¨μ νΈμΆ μ€ννκ³ λΉμ·ν μν μ ν©λλ€. ν μμ
μμμ μ¬λ¬ μμ futureλ€μ ν΄λ§νλ©΄, νμ΄λ¨Έλ₯Ό μΌλ κ²κ³Ό μ΄λ€ I/Oμμ
μ λμμ μνμν¨ ν νμ΄λ¨Έμ I/O μ€ λ¨Όμ λλλ κ²μ κΈ°λ€λ¦¬λ κ²κ³Ό κ°μλμμ±λ ꡬνν μ μμ΅λλ€.
use tokio::io::{self, AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpListener; #[tokio::main] async fn main() -> io::Result<()> { let listener = TcpListener::bind("127.0.0.1:0").await?; println!("ν¬νΈ {}μμ μμ λκΈ°", listener.local_addr()?.port()); loop { let (mut socket, addr) = listener.accept().await?; println!("{addr:?}μμ μ°κ²°"); tokio::spawn(async move { socket.write_all(b"λꡬμΈμ?\n").await.expect("μμΌ μ€λ₯"); let mut buf = vec![0; 1024]; let name_size = socket.read(&mut buf).await.expect("μμΌ μ€λ₯"); let name = std::str::from_utf8(&buf[..name_size]).unwrap().trim(); let reply = format!("{name}λ, μ νν΄ μ£Όμ μ κ°μ¬ν©λλ€.\n"); socket.write_all(reply.as_bytes()).await.expect("μμΌ μ€λ₯"); }); } }
μ΄ μμ λ₯Ό, λ‘컬 μ»΄ν¨ν°μ λ§λ€μ΄ λ src/main.rs
μ 볡μ¬νκ³ κ±°κΈ°μμ μ€ννμΈμ.
nc λλ telnetκ³Ό κ°μ TCP μ°κ²° λꡬλ₯Ό μ¬μ©νμ¬ μ°κ²°ν΄ 보μΈμ.
-
μκ°μλ€μκ² μ΄ μλ²μ λͺ κ°μ ν΄λΌμ΄μΈνΈκ° μ°κ²°λλ©΄ μ΄ μλ²μ μνκ° μ΄λ»κ² λ³ν μ§ κ·Έλ¦Όμ κ·Έλ €λ³΄λλ‘ νμΈμ. μ΄λ€ νμ€ν¬λ€μ΄ μλμ§, μ΄ νμ€ν¬λ€μ Futureλ μ΄λ€ μνμ μλμ§ λ¬Όμ΄λ΄ λλ€.
-
This is the first time weβve seen an
async
block. This is similar to a closure, but does not take any arguments. Its return value is a Future, similar to anasync fn
. -
Async λΈλ‘μ ν¨μλ‘ λ¦¬ν©ν°λ§νκ³
?
λ₯Ό μ¬μ©νμ¬ μ€λ₯ μ²λ¦¬λ₯Ό κ°μ ν΄ λ΄ μλ€.