网络
在 Rust 中处理网络通信涉及到多个标准库和第三方库的组件。标准库中的 std::net
模块提供了处理 TCP 和 UDP 网络通信的基本构建块,而第三方库则提供了更高级的异步处理机制和更丰富的网络协议支持。
Demo
以下是一个使用 Rust 标准库进行 TCP 服务器和客户端通信的基本示例:
TCP 服务器
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
fn handle_client(mut stream: TcpStream) -> std::io::Result<()> {
println!("Incoming connection from: {}", stream.peer_addr()?);
let mut buffer = [0; 512];
loop {
let bytes_read = stream.read(&mut buffer)?;
if bytes_read == 0 { return Ok(()); } // Connection was closed
stream.write(&buffer[..bytes_read])?;
}
}
fn main() -> std::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:7878")?;
println!("Server listening on port 7878");
for stream in listener.incoming() {
let stream = stream?;
handle_client(stream)?;
}
Ok(())
}
TCP 客户端
use std::net::TcpStream;
use std::io::{Read, Write};
fn main() -> std::io::Result<()> {
let mut stream = TcpStream::connect("127.0.0.1:7878")?;
println!("Connected to the server!");
stream.write_all(b"Hello, server!")?;
let mut buffer = [0; 512];
stream.read(&mut buffer)?;
println!("Received from server: {}", String::from_utf8_lossy(&buffer));
Ok(())
}
Tokio
一般而言,编写网络程序面对的瓶颈往往是IO。在等待IO的时候做更多的工作是最有效的优化办法,所以网络程序大都是并发程序。
这是使用 tokio
的异步 TCP Echo 服务器 Demo。
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
async fn handle_client(mut stream: TcpStream) -> tokio::io::Result<()> {
let mut buffer = [0; 1024];
loop {
let bytes_read = stream.read(&mut buffer).await?;
if bytes_read == 0 { break; }
stream.write_all(&buffer[..bytes_read]).await?;
}
Ok(())
}
#[tokio::main]
async fn main() -> tokio::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:7878").await?;
println!("Server listening on port 7878");
loop {
let (stream, _) = listener.accept().await?;
tokio::spawn(async move {
handle_client(stream).await.unwrap();
});
}
}
Reqwest
Reqwest 是一个 Rust 语言编写的非常流行的 HTTP 客户端库,它支持异步和同步两种请求方式。Reqwest 基于 hyper
这一 HTTP 库构建,便于处理 HTTP 客户端操作,并且集成了 tokio
作为异步运行时。
他的接口设计和Python的request库很像。