rust-network - 課題
概要
Rustで低レベルネットワークプログラミングを学び、TCPとUDPを使用した通信を実装する課題です。
マンダトリーパート
必須要件
- TCPエコーサーバー/クライアント
- UDPチャットシステム
- 簡易DNSリゾルバー
インターフェース
// TCPエコーサーバー
pub struct TcpEchoServer {
listener: TcpListener,
}
impl TcpEchoServer {
pub fn bind(addr: &str) -> io::Result<Self>;
pub fn run(&self) -> io::Result<()>;
}
// UDPチャット
pub struct UdpChat {
socket: UdpSocket,
peers: Vec<SocketAddr>,
}
impl UdpChat {
pub fn new(port: u16) -> io::Result<Self>;
pub fn send_message(&self, msg: &str) -> io::Result<()>;
pub fn receive(&self) -> io::Result<(String, SocketAddr)>;
}
// DNSリゾルバー
pub fn resolve(hostname: &str) -> io::Result<Vec<IpAddr>>;
使用例
// TCPエコーサーバー
let server = TcpEchoServer::bind("0.0.0.0:9000")?;
server.run()?;
// TCPクライアント
let mut stream = TcpStream::connect("127.0.0.1:9000")?;
stream.write_all(b"Hello")?;
let mut buf = [0u8; 1024];
let n = stream.read(&mut buf)?;
assert_eq!(&buf[..n], b"Hello");
// UDPチャット
let chat = UdpChat::new(5000)?;
chat.send_message("Hello, everyone!")?;
let (msg, from) = chat.receive()?;
// DNS解決
let addrs = resolve("example.com")?;
println!("{:?}", addrs);
ボーナスパート
ボーナス1: TCP接続プール
- 接続の再利用
ボーナス2: タイムアウト処理
- 読み書きタイムアウト
ボーナス3: NAT穴あけ
- UDPホールパンチング
src/tcp.rs- TCP実装src/udp.rs- UDP実装src/dns.rs- DNSリゾルバーCargo.tomltokio,async-stdは使用不可- 標準ライブラリの
std::netのみ使用可能