当前位置: 首页 > news >正文

Rust 构建 TCP/UDP 网络服务

第四章 异步编程与网络通信

第二节 构建 TCP/UDP 网络服务

在现代应用程序中,网络通信是核心功能之一。本节将重点介绍如何在 Rust 中构建基本的 TCP 和 UDP 网络服务,涵盖实际的代码示例、最佳实践以及最新的技术方案,以帮助开发者掌握网络编程的技巧。


1. 实现一个基本的 TCP 服务器和客户端

1.1 TCP 服务器的实现

我们首先创建一个简单的 TCP 服务器,能够接受客户端的连接并进行数据交互。使用 Tokio 作为异步运行时来处理 TCP 连接。

基本 TCP 服务器代码示例:

use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*;async fn handle_client(mut stream: TcpStream) {let mut buffer = [0; 1024];loop {let bytes_read = match stream.read(&mut buffer).await {Ok(0) => return, // 连接关闭Ok(n) => n,Err(e) => {eprintln!("读取错误: {}", e);return;}};println!("收到: {}", String::from_utf8_lossy(&buffer[..bytes_read]));if let Err(e) = stream.write_all(&buffer[..bytes_read]).await {eprintln!("写入错误: {}", e);return;}}
}#[tokio::main]
async fn main() {let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();println!("TCP 服务器在 127.0.0.1:8080 启动");loop {let (socket, _) = listener.accept().await.unwrap();tokio::spawn(handle_client(socket));}
}

关键点:

  • TcpListener 用于监听传入连接。
  • 每当接收到连接时,handle_client 函数在新的任务中处理该连接。
  • 服务器能并发处理多个连接。
1.2 TCP 客户端的实现

接下来,我们将实现一个简单的 TCP 客户端,与服务器进行连接并发送数据。

基本 TCP 客户端代码示例:

use tokio::net::TcpStream;
use tokio::prelude::*;#[tokio::main]
async fn main() {let mut stream = TcpStream::connect("127.0.0.1:8080").await.unwrap();let message = "Hello, TCP Server!";stream.write_all(message.as_bytes()).await.unwrap();let mut buffer = [0; 1024];let size = stream.read(&mut buffer).await.unwrap();println!("服务器回复: {}", String::from_utf8_lossy(&buffer[..size]));
}

关键点:

  • 客户端连接到 TCP 服务器并发送消息。
  • 等待并接收服务器的回复。

2. UDP 的使用案例与实践

UDP 是一种无连接的协议,适用于实时性要求高的场景,如视频会议、在线游戏等。以下是如何在 Rust 中实现一个基本的 UDP 服务器和客户端。

2.1 UDP 服务器的实现

基本 UDP 服务器代码示例:

use tokio::net::UdpSocket;
use tokio::prelude::*;#[tokio::main]
async fn main() {let socket = UdpSocket::bind("127.0.0.1:8080").await.unwrap();println!("UDP 服务器在 127.0.0.1:8080 启动");let mut buf = [0; 1024];loop {let (size, addr) = socket.recv_from(&mut buf).await.unwrap();println!("收到来自 {:?} 的消息: {}", addr, String::from_utf8_lossy(&buf[..size]));// 回送数据socket.send_to(&buf[..size], &addr).await.unwrap();}
}

关键点:

  • 使用 UdpSocket 创建一个 UDP 服务器。
  • 服务器接收数据并将其回送给客户端。
2.2 UDP 客户端的实现

基本 UDP 客户端代码示例:

use tokio::net::UdpSocket;
use tokio::prelude::*;#[tokio::main]
async fn main() {let socket = UdpSocket::bind("127.0.0.1:8081").await.unwrap();let message = b"Hello, UDP Server!";socket.send_to(message, "127.0.0.1:8080").await.unwrap();let mut buf = [0; 1024];let (size, _) = socket.recv_from(&mut buf).await.unwrap();println!("服务器回复: {}", String::from_utf8_lossy(&buf[..size]));
}

关键点:

  • 客户端发送数据到 UDP 服务器并接收回复。
  • 使用 send_torecv_from 进行数据传输。

3. 处理并发连接的实现方式

在实际的应用中,处理并发连接是非常重要的。我们将讨论几种不同的处理方式,包括使用 Tokio 的任务和通道。

3.1 使用 Tokio 的任务处理并发连接

在 TCP 服务器示例中,我们使用 tokio::spawn 为每个连接创建一个新的异步任务,这样可以处理多个连接而不会阻塞主线程。

示例回顾:

tokio::spawn(handle_client(socket));
3.2 使用通道进行消息传递

通过 Tokio 的通道,我们可以在不同的任务之间传递消息。这对于处理复杂的并发逻辑非常有用。

使用通道的示例:

use tokio::sync::mpsc;#[tokio::main]
async fn main() {let (tx, mut rx) = mpsc::channel(32);tokio::spawn(async move {while let Some(message) = rx.recv().await {println!("接收到消息: {}", message);}});tx.send("Hello from the main task!").await.unwrap();
}
3.3 实现连接池

对于高并发场景,连接池是一种常见的解决方案。连接池管理一组 TCP/UDP 连接,以减少连接的创建和关闭开销。

基本的连接池结构:

use std::collections::VecDeque;
use tokio::net::TcpStream;struct ConnectionPool {connections: VecDeque<TcpStream>,
}impl ConnectionPool {fn new(size: usize) -> Self {Self {connections: VecDeque::with_capacity(size),}}// 获取连接fn get_connection(&mut self) -> Option<TcpStream> {self.connections.pop_front()}// 返回连接fn return_connection(&mut self, conn: TcpStream) {self.connections.push_back(conn);}
}

连接池的应用:

  • 连接池可以在高并发的场景中显著提高性能。
  • 适当的连接管理策略可以减少连接建立的开销。

4. 实际应用场景

在实际项目中,网络服务的实现通常涉及复杂的业务逻辑和多个组件的协作。我们将讨论几个常见的应用场景以及实现的要点。

4.1 实时聊天应用
  • 设计:使用 TCP 或 WebSocket 协议。
  • 关键点
    • 使用 JSON 或 Protobuf 进行消息格式化。
    • 实现用户认证和授权机制。
    • 管理用户的在线状态。
4.2 视频流服务
  • 设计:通常使用 UDP 或 RTP 协议。
  • 关键点
    • 数据包丢失的处理和重传机制。
    • 使用流式传输技术,如 HLS 或 DASH。
    • 处理并发用户的性能优化。
4.3 物联网设备通信
  • 设计:使用 MQTT 或 CoAP 协议。
  • 关键点
    • 低功耗、高延迟网络的适应性。
    • 设备的状态监控和管理。
    • 安全性和数据加密。

小结

本节深入探讨了如何在 Rust 中构建 TCP 和 UDP 网络服务。通过实际的代码示例和并发处理的实现方式,开发者可以掌握基本的网络编程技能。无论是实现基本的客户端和服务器,还是处理并发连接和消息传递,Rust 提供了强大而灵活的工具。

进一步学习

  • Rust 官方文档:Rust Networking
  • Tokio 官方文档:Tokio
  • 使用 UDP 的最佳实践:关注性能和数据包丢失的处理。

相关文章:

Rust 构建 TCP/UDP 网络服务

第四章 异步编程与网络通信 第二节 构建 TCP/UDP 网络服务 在现代应用程序中&#xff0c;网络通信是核心功能之一。本节将重点介绍如何在 Rust 中构建基本的 TCP 和 UDP 网络服务&#xff0c;涵盖实际的代码示例、最佳实践以及最新的技术方案&#xff0c;以帮助开发者掌握网络…...

docker镜像文件导出导入

1. 导出容器&#xff08;包含内部服务&#xff09;为镜像文件&#xff08;docker commit方法&#xff09; 原理&#xff1a;docker commit命令允许你将一个容器的当前状态保存为一个新的镜像。这个新镜像将包含容器内所有的文件系统更改&#xff0c;包括安装的软件、配置文件等…...

ViT面试知识点

文章目录 VITCLIPBlipSAMLSegFast TransformerYOLO系列问题 BatchNorm是对一个batch-size样本内的每个特征做归一化&#xff0c;LayerNorm是对每个样本的所有特征做归一化。 Layer Normalization&#xff08;层归一化&#xff0c;简称LayerNorm&#xff09;是一种在深度学习中…...

ChatGPT 和 RAG(检索增强生成)的区别;ChatGPT 和 RAG 的联系

目录 ChatGPT 和 RAG(检索增强生成)的区别 知识来源与利用方式 回答准确性和可靠性 模型架构和复杂性 适用场景 ChatGPT 和 RAG 的联系 ChatGPT 和 RAG(检索增强生成)的区别 知识来源与利用方式 ChatGPT:是基于大规模预训练的语言模型,知识是在预训练过程中从大量的…...

qt获取本机IP和定位

前言&#xff1a; 在写一个天气预报模块时&#xff0c;需要一个定位功能&#xff0c;在网上翻来翻去才找着&#xff0c;放在这里留着回顾下&#xff0c;也帮下有需要的人 正文&#xff1a; 一开始我想着直接调用百度地图的API来定位&#xff0c; 然后我就想先获取本机IP的方…...

CodeQL学习笔记(5)-CodeQL for Java(AST、元数据、调用图)

最近在学习CodeQL&#xff0c;对于CodeQL就不介绍了&#xff0c;目前网上一搜一大把。本系列是学习CodeQL的个人学习笔记&#xff0c;根据个人知识库笔记修改整理而来的&#xff0c;分享出来共同学习。个人觉得QL的语法比较反人类&#xff0c;至少与目前主流的这些OOP语言相比&…...

服装品牌零售业态融合中的创新发展:以开源 AI 智能名片 S2B2C 商城小程序为视角

摘要&#xff1a;本文以服装品牌零售业态融合为背景&#xff0c;探讨信息流优化和资金流创新的重要作用&#xff0c;并结合开源 AI 智能名片 S2B2C 商城小程序&#xff0c;分析其如何进一步推动服装品牌在零售领域的发展&#xff0c;提高运营效率和用户体验&#xff0c;实现商业…...

前端将网页转换为pdf并支持下载与上传

1.pdf下载 handleExport() {const fixedH document.getElementById("fixed-h");const pageOne document.getElementById("mix-print-box-one");const pageTwo document.getElementById("mix-print-box-two");fixedH.style.height 30vh;pageO…...

Android 依赖统一配置管理(Version Catalogs)

最近升级了Android Studio版本到Koala Feature Drop | 2024.1.2&#xff0c;新建项目后发现项目配置又有变化&#xff0c;默认开始使用了一个名叫 Gradle 版本目录的东西&#xff0c;当然也可以称之为依赖统一配置管理&#xff0c;一开始还有点陌生&#xff0c;但是经过一番了解…...

如何为数据看板产品接入实时行情接口并展示行情

在金融科技领域&#xff0c;实时数据是分析和决策的关键因素。通过AllTick的实时行情API&#xff0c;您可以轻松将实时市场数据集成到数据看板产品中&#xff0c;为用户提供丰富的市场洞察。本文将详细介绍如何使用AllTick API&#xff0c;通过WebSocket协议接收并展示实时市场…...

数据结构 C/C++(实验一:线性表)

&#xff08;大家好&#xff0c;今天分享的是数据结构的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 提要&#xff1a;实验题目 一、实验目的 二、实验内容及要求 三、算法思想 实验1 实验2 四、源程序及注释 …...

使用WebStorm开发Vue3项目

记录一下使用WebStorm开发Vu3项目时的配置 现在WebStorm可以个人免费使用啦&#xff01;&#x1f929; 基本配置 打包工具&#xff1a;Vite 前端框架&#xff1a;ElementPlus 开发语言&#xff1a;Vue3、TypeScript、Sass 代码检查&#xff1a;ESLint、Prettier IDE&#xf…...

Linux高阶——1103——Signal信号机制

1、信号机制 在linux和unix系统下&#xff0c;如果想要处置(挂起&#xff0c;结束)进程&#xff0c;可以使用信号&#xff0c;经典消息机制&#xff0c;所以进程包括系统进程都是利用信号处置进程的 kill -l——查看所有系统支持的信号 1-31号信号——Unix经典信号&#xff…...

如何编写STM32的定时器程序

编写STM32的定时器程序通常涉及以下步骤&#xff1a; 1. 选择定时器和时钟配置 首先&#xff0c;你需要选择一个可用的定时器&#xff08;TIM&#xff09;&#xff0c;并配置其时钟源。时钟源可以是内部时钟或外部时钟&#xff0c;通常通过RCC&#xff08;Reset and Clock Con…...

【C++】C++的单例模式、跟踪内存分配的简单方法

二十四、C的单例模式、跟踪内存分配的简单方法 1、C的单例模式 本小标题不是讨论C的语言特性&#xff0c;而是一种设计模式&#xff0c;用于确保一个类在任何情况下都只有一个实例&#xff0c;并提供一个全局访问点来获取这个实例。即C的单例模式。这种模式常用于资源管理&…...

构建一个导航栏web

<!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}#menu{background-color:purple;width: 100px;height: 50px;}.item{float: left;/* 浮动标签可以让块标签&#xff0c…...

【Linux】Linux安全与密钥登录指南

在使用Linux服务器时&#xff0c;确保服务器的安全至关重要。本文将为你介绍一些关键的Linux安全措施&#xff0c;包括开启密钥登录、查看登录日志、限制登录IP以及查看系统中能够登录的账号。以下内容适合小白用户&#xff0c;通过简单的操作就能有效提升服务器的安全性。 目录…...

数据采集之scrapy框架

本博文使用基本框架完成搜房网或者其他网站的数据爬取&#xff08;重点理解 scrapy 框架的构建过程&#xff0c;使用回调函数&#xff0c;完成数据采集和数据处理&#xff09; 包结构目录如下图所示&#xff1a; 主要代码&#xff1a; &#xff08;sfw.py&#xff09; # -*- …...

ReactPress—基于React的免费开源博客CMS内容管理系统

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress 欢迎提出宝贵的建议&#xff0c;感谢Star。 ![ReactPress](https://i-blog.csdnimg.cn/direct/0720f155edaa4eadba796f4d96d394d7.png#pic_center ReactPress 是使用React开发的开源发布平台&…...

Android 解决飞行模式下功耗高,起伏波动大的问题

根据现象抓log如下&#xff1a; 10-31 15:26:16.149066 940 3576 I android.hardware.usb1.2-service-mediatekv2: uevent_event change/devices/platform/soc/10026000.pwrap/10026000.pwrap:mt6366/mt6358-gauge/power_supply/battery 10-31 15:26:16.149245 940 3576 …...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...