Rust 多线程和网络编程

一、综合示例

1、效果展示

在这里插入图片描述

2、源码分享

use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::thread;

fn handle_client(mut stream: TcpStream) {
    let mut buffer = [0; 512];
    loop {
        match stream.read(&mut buffer) {
            Ok(size) => {
                if size == 0 {
                    // Connection closed
                    println!("Client disconnected: {}", stream.peer_addr().unwrap());
                    break;
                }
                stream.write(&buffer[0..size]).unwrap();
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        }
    }
}

fn main() {


    let lis = TcpListener::bind("127.0.0.1:12345").unwrap();
    for stream in lis.incoming() {
        match stream {
            Ok(stream) => {
                println!("Client connected: {}", stream.peer_addr().unwrap());
                thread::spawn(move || {
                    handle_client(stream);
                });
            }
            Err(e) => {
                eprintln!("Error: {}", e);
            }
        }
    }
}

二、多线程

Rust 通过所有权机制和类型系统,在编译期即可避免数据竞争,实现安全高效的多线程编程。以下从核心概念到实践逐步解析:

1、线程创建

使用 std::thread::spawn 创建新线程,返回 JoinHandle 用于等待线程结束:

use std::thread;

fn main() {
    let handle = thread::spawn(|| {
        println!("子线程运行中!");
    });

    handle.join().unwrap(); // 等待子线程结束
    println!("主线程结束");
}

2、线程间通信

通道(Channel) 是消息传递的核心工具,基于生产者-消费者模型:

use std::sync::mpsc; // 多生产者单消费者

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        tx.send("子线程消息".to_string()).unwrap();
    });

    println!("收到: {}", rx.recv().unwrap());
}
  • mpsc::channel() 创建通道
  • tx.send() 发送数据
  • rx.recv() 阻塞接收数据

3、共享状态并发

互斥锁(Mutex) 保护共享数据:

use std::sync::{Mutex, Arc};

fn main() {
    let counter = Arc::new(Mutex::new(0)); // 原子引用计数包装
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1; // 修改共享数据
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }
    println!("最终值: {}", *counter.lock().unwrap());
}
  • Arc<T> 实现多线程安全引用计数
  • Mutex::lock() 获取锁,保证独占访问

4、高级同步原语

  • 屏障(Barrier):协调多个线程同时到达某点
    use std::sync::{Arc, Barrier};
    
    let barrier = Arc::new(Barrier::new(3)); // 等待3个线程
    
  • 条件变量(Condvar):与互斥锁配合实现复杂同步
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    

5、原子操作

对简单类型使用原子变量避免锁开销:

use std::sync::atomic::{AtomicUsize, Ordering};

let count = AtomicUsize::new(0);
count.fetch_add(1, Ordering::SeqCst); // 原子递增
  • Ordering 指定内存顺序(如 Relaxed, Acquire, Release

6、线程池实践

使用 rayon 库实现高效并行迭代:

# Cargo.toml
[dependencies]
rayon = "1.7"
use rayon::prelude::*;

fn main() {
    let v = vec![1, 2, 3, 4];
    v.par_iter().for_each(|n| println!("{}", n)); // 自动线程池
}

关键特性对比

机制适用场景优势
通道任务流水线零共享数据,避免锁竞争
互斥锁复杂共享状态数据修改灵活
原子操作计数器/标志位无锁,高性能
线程池批量任务处理自动负载均衡

安全原则

  • 编译期检查:所有权系统强制要求:
    • 跨线程传递的数据必须实现 Send trait(表示可安全转移所有权)
    • 共享引用需实现 Sync trait(表示可安全跨线程共享)
  • 错误预防:常见问题如死锁仍需开发者注意,可通过 MutexGuard 作用域限定锁周期

三、网络编程

Rust 凭借其内存安全、零成本抽象和高性能特性,成为网络编程的理想选择。以下是核心概念与实现步骤:


1、Rust 网络编程基础

  • 核心库std::net 提供同步网络操作(TCP/UDP)。
  • 异步运行时tokioasync-std 实现非阻塞 I/O(推荐)。
  • 关键协议
    • TCP:可靠流式传输(如 HTTP/WebSocket)。
    • UDP:低延迟数据报传输(如 DNS/游戏协议)。

2、同步 TCP 示例

use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};

// 服务端
fn tcp_server() -> std::io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:8080")?;
    for stream in listener.incoming() {
        let mut stream = stream?;
        let mut buffer = [0; 1024];
        stream.read(&mut buffer)?;
        stream.write_all(b"Received")?;
    }
    Ok(())
}

// 客户端
fn tcp_client() -> std::io::Result<()> {
    let mut stream = TcpStream::connect("127.0.0.1:8080")?;
    stream.write_all(b"Hello")?;
    let mut response = [0; 8];
    stream.read_exact(&mut response)?;
    println!("Server response: {:?}", response);
    Ok(())
}

3、异步 TCP 示例(使用 Tokio)

# Cargo.toml 依赖
[dependencies]
tokio = { version = "1.0", features = ["full"] }
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

// 异步服务端
async fn async_tcp_server() -> tokio::io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    loop {
        let (mut socket, _) = listener.accept().await?;
        tokio::spawn(async move {
            let mut buf = [0; 1024];
            socket.read(&mut buf).await?;
            socket.write_all(b"Async Response").await
        });
    }
}

// 异步客户端
async fn async_tcp_client() -> tokio::io::Result<()> {
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
    stream.write_all(b"Async Hello").await?;
    let mut response = [0; 14];
    stream.read_exact(&mut response).await?;
    println!("Async response: {:?}", response);
    Ok(())
}

4、UDP 通信示例

use std::net::UdpSocket;

fn udp_example() -> std::io::Result<()> {
    // 服务端
    let server_socket = UdpSocket::bind("127.0.0.1:8081")?;
    let mut buf = [0; 1024];
    let (_, client_addr) = server_socket.recv_from(&mut buf)?;
    server_socket.send_to(b"UDP ACK", client_addr)?;

    // 客户端
    let client_socket = UdpSocket::bind("127.0.0.1:0")?;
    client_socket.send_to(b"UDP Data", "127.0.0.1:8081")?;
    let mut ack = [0; 7];
    client_socket.recv_from(&mut ack)?;
    println!("UDP ACK: {:?}", ack);
    Ok(())
}

5、高级主题

  • 协议设计
    • 使用 serde 序列化数据(JSON/Protobuf)。
    • 实现自定义二进制协议(如 byteorder 库)。
  • 性能优化
    • 零拷贝技术(bytes::Bytes)。
    • 连接池管理(bb8 库)。
  • 安全实践
    • TLS 加密(rustls 库)。
    • 防 DoS 攻击(速率限制/超时控制)。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小灰灰搞电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值