温馨提示×

Linux下Rust网络编程入门指南

小樊
38
2025-11-20 17:35:46
栏目: 编程语言

Linux下Rust网络编程入门指南

一 环境准备与项目初始化

  • 安装 Rust 工具链(Linux):执行命令:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh,安装完成后按提示将 Rust 加入 PATH
  • 创建项目:cargo new rust_network_demo && cd rust_network_demo
  • 运行与调试:cargo run 构建并运行;开发阶段可使用 cargo check 快速语法检查。

二 阻塞式 TCP 编程 std::net

  • 适用场景:学习、原型、连接并发不高的服务。
  • 核心类型:TcpListenerTcpStream,以及地址类型如 IpAddr / SocketAddr
  • 示例(回显服务器与客户端,端口 7878):
// 服务器端 src/main.rs
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};

fn handle_client(mut stream: TcpStream) {
    let mut buf = [0; 1024];
    loop {
        match stream.read(&mut buf) {
            Ok(0) => break, // 对端关闭
            Ok(n) => {
                if let Err(e) = stream.write_all(&buf[..n]) {
                    eprintln!("write error: {}", e);
                    break;
                }
            }
            Err(e) => {
                eprintln!("read error: {}", e);
                break;
            }
        }
    }
}

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(())
}
// 客户端 src/bin/client.rs
use std::io::{Read, Write};
use std::net::TcpStream;

fn main() -> std::io::Result<()> {
    let mut stream = TcpStream::connect("127.0.0.1:7878")?;
    stream.write_all(b"Hello, Rust TCP\n")?;
    let mut buf = [0; 1024];
    let n = stream.read(&mut buf)?;
    println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
    Ok(())
}
  • 运行步骤:在终端 A 运行 cargo run;在终端 B 运行 cargo run --bin client
  • 测试工具:也可用 nc 127.0.0.1 7878telnet 127.0.0.1 7878 进行交互测试。

三 异步 TCP 编程 Tokio

  • 适用场景:高并发、I/O 密集的网络服务。
  • 依赖配置(Cargo.toml):
[dependencies]
tokio = { version = "1", features = ["full"] }
  • 示例(异步回显服务器,端口 7878):
// src/main.rs
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:7878").await?;
    println!("Async server listening on 127.0.0.1:7878");

    loop {
        let (mut socket, addr) = listener.accept().await?;
        println!("Accepted connection from {:?}", addr);

        tokio::spawn(async move {
            let mut buf = [0; 1024];
            loop {
                let n = match socket.read(&mut buf).await {
                    Ok(0) => return, // 对端关闭
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("read error: {}", e);
                        return;
                    }
                };
                if let Err(e) = socket.write_all(&buf[..n]).await {
                    eprintln!("write error: {}", e);
                    return;
                }
            }
        });
    }
}
  • 运行与测试:终端 A 运行 cargo run;终端 B 使用 nc/telnet 或编写对应的异步客户端进行连接测试。

四 关键要点与常见问题

  • 选择同步还是异步
    • 同步(std::net):实现简单,适合学习与原型;并发连接多时每个连接占用一个线程,资源消耗较大。
    • 异步(Tokio):基于事件循环与任务调度,少量线程即可支撑大量并发连接,是高性能网络服务的首选。
  • 地址与协议族
    • 学习阶段常用 127.0.0.1(仅本机访问);对外服务应绑定 0.0.0.0(所有地址)或指定网卡 IP,并确保防火墙放行对应端口。
  • 粘包与消息帧
    • TCP 是字节流,应用层需自行界定消息边界;常见做法有:基于分隔符(如 \n)、基于长度前缀(先发送 N 字节长度再发送负载)。
  • 常见错误与排查
    • 端口被占用:更换端口或释放占用进程;
    • 连接被拒绝:检查服务是否监听、IP/端口是否正确、防火墙策略;
    • 对端提前关闭:读取返回 0 即表示对端关闭,应优雅退出读写循环。

五 下一步学习路径与生态

  • HTTP 服务与客户端
    • 使用 Hyper 构建高性能 HTTP/1HTTP/2 服务与客户端;适合 RESTful API、反向代理等。
  • Web 框架
    • Actix-Web(高性能、Actor 模型)、Warp(基于过滤器链、集成 WebSocket)、Tide(轻量易用)。
  • 实时通信
    • tokio-tungstenite 实现 WebSocket,适合聊天、实时推送等场景。
  • 安全与传输
    • tokio-rustls / native-tls 为 TCP 增加 TLSQuinn 实现 QUIC/HTTP/3,适合低延迟与高并发传输。

0