Ubuntu 上怎样实现 Rust 网络编程:从环境搭建到最小 TCP 服务跑通

Owen
Owen
发布时间:2026-08-24 | 63人浏览过
原创

前言

在 Ubuntu 上开始 Rust 网络编程,真正容易卡住的往往不是语法,而是工具链、异步依赖和服务验证有没有一次打通。下面用一个最小 TCP 服务把安装 Rust、接入 Tokio、编写异步监听和本地测试串成完整流程,读完后你能判断自己已经具备哪些基础,以及下一步该往 HTTP、WebSocket 还是协议解析方向扩展。

在 Ubuntu 上开始 Rust 网络编程,真正的门槛通常不是“会不会写代码”,而是环境、依赖和运行方式能不能一次打通。下面就用一个可直接运行的 TCP 服务示例,把安装 Rust、引入 Tokio、编写异步服务以及本地验证的过程串起来,帮助你判断自己已经完成了哪一步、下一步又该扩展到哪里。

先把 Ubuntu 上的 Rust 环境装完整

如果是从零开始,第一步先把 Rust 工具链装好。常见做法是直接使用 rustup 安装:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

安装结束后,还要刷新当前 shell 环境,否则新装的 cargo、rustc 可能暂时不可用:

source $HOME/.cargo/env

做完这一步,你就具备了创建项目、下载依赖和编译程序的基础条件。对后续网络编程来说,这一步虽然简单,但如果环境变量没生效,后面的项目初始化和运行都会卡住。

创建项目,并加入异步网络依赖

Rust 网络程序通常会先从一个独立项目开始。这里直接用 cargo 创建一个新工程:

Rust 网络编程在 Ubuntu 上的搭建与验证流程图
Ubuntu 下 Rust 网络项目的最短搭用流程图梳理从安装工具链、创建项目到加入 Tokio 依赖的最短落地路径。
cargo new rust_network_program
cd rust_network_program

项目创建完成后,需要为网络服务准备运行时依赖。原文选择的是 tokio,这也是 Rust 生态里最常见的异步运行时之一。把下面内容加入 Cargo.toml:

[dependencies]
tokio = { version = "1", features = ["full"] }

tokio 的作用不只是“让异步语法能跑起来”,它还提供了 TCP、定时器、任务调度等网络开发常用能力。这里启用 features = ["full"],相当于先把常用组件一次性配齐,便于快速搭出第一个服务。

用 Tokio 写一个最小可运行的 TCP 服务器

环境和依赖准备好之后,就可以在 src/main.rs 里写核心逻辑。这个示例程序做的事情很直接:监听 127.0.0.1:8080,接受客户端连接,读取请求后返回当前时间戳。

Tokio TCP 服务器处理连接并返回时间戳的结构图
最小 TCP 服务的异步处理结构把监听、接收连接、异步任务和时间戳回写拆开后,示例代码的结构会更容易理解。
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use std::time::{SystemTime, UNIX_EPOCH};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    loop {
        let (mut socket, _) = listener.accept().await?;
        tokio::spawn(async move {
            let mut buffer = [0; 1024];
            loop {
                let bytes_read = match socket.read(&mut buffer).await {
                    Ok(n) if n == 0 => return,
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("Failed to read from socket: {:?}", e);
                        return;
                    }
                };
                let now = SystemTime::now()
                    .duration_since(UNIX_EPOCH)
                    .expect("Time went backwards")
                    .as_secs();
                let time_str = format!("Current time: {}\n", now);
                if let Err(e) = socket.write_all(time_str.as_bytes()).await {
                    eprintln!("Failed to write to socket: {:?}", e);
                    return;
                }
            }
        });
    }
}

这段代码可以拆成几个关键点来理解:

1. 监听本地端口

TcpListener::bind("127.0.0.1:8080") 表示服务只监听本机的 8080 端口。也就是说,当前示例主要用于本地开发和验证,而不是直接对外提供访问。

2. 接收新连接

listener.accept().await? 会持续等待新的客户端连入。每接到一个连接,程序就拿到一个可读写的 socket。

Rust TCP 服务的本地验证结果与后续扩展方向对照图
本地验证通过后,该如何继续扩展测试命令能否拿到时间戳,基本对应着环境、依赖、监听和异步读写是否已经全部打通。

3. 为每个连接启动异步任务

示例使用 tokio::spawn 为每个连接分配一个独立任务。这样多个客户端同时访问时,服务不会因为处理单个连接而阻塞整个监听循环,这是异步网络模型最直接的价值之一。

4. 读取数据并返回时间戳

服务端会先调用 socket.read(&mut buffer).await 读取客户端发送的数据。随后通过 SystemTime::now() 获取当前时间,并转换为基于 UNIX_EPOCH 的秒级时间戳,再用 socket.write_all(...).await 写回客户端。

这里的 bytes_read 虽然没有继续参与业务处理,但它仍然承担着判断连接状态的作用:如果读取结果为 0,就说明对端已经关闭连接,任务会直接退出。

5. 错误处理方式很适合入门验证

示例中对读写错误采用 eprintln! 输出,并在出错后结束当前连接任务。这种做法足够轻量,适合确认网络栈、异步运行时和基本收发逻辑是否正常工作。等后续进入正式项目,再考虑更细致的日志、超时和重试策略。

编译运行后,怎么确认服务真的可用

代码写完后,先直接编译并运行:

cargo run

如果依赖下载、编译和启动都正常,说明项目结构和 Tokio 运行时已经能够在 Ubuntu 上顺利工作。接下来要验证的是:服务是否真的监听成功,并且能正确回应客户端。

最简单的测试方式,是另开一个终端,用 telnet 或 nc 连接本地端口:

telnet 127.0.0.1 8080

或者:

nc 127.0.0.1 8080

连接建立后,服务端会返回当前时间戳。如果你已经看到响应,基本可以说明以下几件事都没问题:

  • Rust 工具链已经正确安装;
  • cargo 能正常解析并构建 tokio 依赖;
  • 本地 TCP 监听和连接建立是通的;
  • 异步读取与写回逻辑已经跑通。

从入门角度看,这种验证方式非常有效,因为它不是停留在“代码编译过了”,而是进一步确认一个完整的网络请求和响应链路已经实际发生。

跑通最小示例后,可以往哪些方向扩展

这个 TCP 时间戳服务只是起点,但它已经覆盖了 Rust 网络编程最基础的几块内容:运行时、连接处理、异步读写和错误退出。接下来如果要做更贴近实际业务的服务,可以沿着生态继续扩展。

原文提到几个常见方向:

  • 如果目标是 HTTP 服务器,可以考虑 hyper;
  • 如果要处理 WebSocket,可以使用 tokio-tungstenite;
  • 如果需要更高性能的协议解析,nom 和 bytes 是常见组合。

这几个库对应的是不同层次的问题:tokio 负责异步运行和底层 IO,hyper 更偏 HTTP 协议抽象,tokio-tungstenite 面向长连接实时通信,而 nom、bytes 更适合自定义协议和高效字节流处理。

换句话说,如果你已经能把本文这个例子跑通,就说明 Ubuntu 下的 Rust 网络开发基础环境已经具备。后续无论是做本地 TCP 服务、HTTP 接口,还是 WebSocket 应用,都可以在这个基础上继续往上搭,而不必再回头排查工具链和基础异步模型的问题。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表