1. 准备工作:安装Rust与创建项目
在Linux环境下开始Rust网络编程前,需先完成环境配置。通过以下命令安装Rust(包含Cargo包管理器):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
安装完成后,将~/.cargo/bin添加到PATH环境变量(通常安装脚本会自动提示)。接着使用Cargo创建新项目:
cargo new rust_networking && cd rust_networking
这会生成一个包含Cargo.toml(依赖配置)和src/main.rs(主程序)的基础项目结构。
2. 同步网络编程:使用标准库std::net
Rust标准库的std::net模块提供了TCP/UDP的基础同步接口,适合简单的同步网络应用。
127.0.0.1:7878的TCP服务器,接受客户端连接并回显收到的消息:use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
fn handle_client(mut stream: TcpStream) {
let mut buffer = [0; 1024];
match stream.read(&mut buffer) {
Ok(size) if size > 0 => {
// 回显消息到客户端
if let Err(e) = stream.write_all(&buffer[..size]) {
eprintln!("Write error: {}", e);
}
}
Ok(_) => println!("Client disconnected"),
Err(e) => eprintln!("Read error: {}", e),
}
}
fn main() -> std::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:7878")?;
println!("Server listening on 127.0.0.1:7878");
for stream in listener.incoming() {
match stream {
Ok(stream) => {
// 为每个连接创建新线程(阻塞式)
std::thread::spawn(|| handle_client(stream));
}
Err(e) => eprintln!("Accept error: {}", e),
}
}
Ok(())
}
use std::io::{Read, Write};
use std::net::TcpStream;
fn main() -> std::io::Result<()> {
let mut stream = TcpStream::connect("127.0.0.1:7878")?;
let message = "Hello, Rust Server!";
stream.write_all(message.as_bytes())?;
println!("Sent: {}", message);
let mut buffer = [0; 1024];
let size = stream.read(&mut buffer)?;
println!("Received: {}", String::from_utf8_lossy(&buffer[..size]));
Ok(())
}
同步模型的缺点是每个连接会阻塞当前线程,无法高效处理高并发场景。3. 异步网络编程:使用Tokio库
对于高并发需求,推荐使用Tokio异步运行时。Tokio提供非阻塞I/O和任务调度,能显著提升性能。
Cargo.toml中添加以下配置(启用完整功能):[dependencies]
tokio = { version = "1", features = ["full"] }
#[tokio::main]宏启动异步运行时,通过tokio::spawn为每个连接创建异步任务:use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
println!("Async server listening on 127.0.0.1:8080");
loop {
// 异步接受连接
let (mut socket, _) = listener.accept().await?;
// 为每个连接生成异步任务
tokio::spawn(async move {
let mut buffer = [0; 1024];
loop {
match socket.read(&mut buffer).await {
Ok(size) if size == 0 => return, // 客户端断开
Ok(size) => {
// 异步回显消息
if let Err(e) = socket.write_all(&buffer[..size]).await {
eprintln!("Write error: {}", e);
return;
}
}
Err(e) => {
eprintln!("Read error: {}", e);
return;
}
}
}
});
}
}
tokio::net::TcpStream和await关键字处理异步操作:use tokio::io::{AsyncWriteExt, AsyncReadExt};
use tokio::net::TcpStream;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
let message = "Hello, Async Rust Server!";
stream.write_all(message.as_bytes()).await?;
println!("Sent: {}", message);
let mut buffer = [0; 1024];
let size = stream.read(&mut buffer).await?;
println!("Received: {}", String::from_utf8_lossy(&buffer[..size]));
Ok(())
}
异步模型的优势在于单线程即可处理大量并发连接,避免了线程切换的开销。4. 关键概念与注意事项
TcpStream)的正确管理,避免数据竞争和内存泄漏。例如,在异步任务中传递socket时,需使用move关键字转移所有权。match或?运算符处理Result类型,避免程序崩溃。tokio::spawn会将任务分发到线程池,充分利用多核CPU资源。tokio-rustls库)、HTTP服务器(如actix-web或rocket框架)、WebSocket通信等高级功能。