ํ์คํฌ
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 ๋ธ๋ก์ ํจ์๋ก ๋ฆฌํฉํฐ๋งํ๊ณ
?
๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ฐ์ ํด ๋ด ์๋ค.