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

Rust Web 全栈开发(一):构建 TCP Server

Rust Web 全栈开发(一):构建 TCP Server

  • Rust Web 全栈开发(一):构建 TCP Server
    • 标准库的 std::net 模块
      • TCP 通信
      • UDP 通信
      • 地址表示
    • 新建项目
    • 建立连接
    • 收发数据

Rust Web 全栈开发(一):构建 TCP Server

参考视频:https://www.bilibili.com/video/BV1RP4y1G7KF

标准库的 std::net 模块

std::net 是 Rust 标准库中提供基础、跨平台网络 I/O 功能的核心模块。它主要处理 TCP 和 UDP 协议的通信,提供了同步(阻塞式)的网络操作接口。它是构建网络应用程序的基础,通常用于实现服务器、客户端以及点对点通信。

TCP 通信

TcpStream 代表一个 TCP 连接(客户端或服务器端已建立的连接),提供读写功能。

TcpListener 代表一个 TCP 服务器套接字,绑定到特定地址和端口,监听连接请求。

服务器创建监听套接字,接受来自客户端的连接请求。accept() 返回一个 TcpStream 用于与特定客户端通信。

UDP 通信

UdpSocket 代表一个 UDP 套接字,提供无连接的数据报发送和接收。消息是离散的,不保证顺序、可靠性和到达。

用途:DNS 查询、实时音视频流、游戏状态更新、广播/组播等场景,对延迟敏感但能容忍少量丢包。

地址表示

std::net 提供了表示网络地址的关键类型:IpAddr、Ipv4Addr、Ipv6Addr、SocketAddr,等等。

新建项目

首先用 RustRover 新建一个二进制项目。

修改 Cargo.toml 文件,配置为工作区:

[workspace]

然后再在该目录下新建两个成员包:tcpserver、tcpclient。

cargo new tcpserver
cargo new tcpclient

在这里插入图片描述

在工作区内运行 cargo new 会自动将新创建的包添加到工作区内 Cargo.toml 的 [workspace] 定义中的 members 键中,如下所示:

在这里插入图片描述

此时,我们可以通过运行 cargo build 来构建工作区。项目目录下的文件应该是这样的:

├── Cargo.lock
├── Cargo.toml
├── tcpclient
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── tcpserver
│   ├── Cargo.toml
│   └── src
│       └── main.rs
└── target

更多关于工作区的知识,请参考:Rust 学习笔记:Cargo 工作区

建立连接

打开 tcpserver 成员包下的 main.rs,编写代码:

use std::net::TcpListener;fn main() {let listener = TcpListener::bind("127.0.0.1:3000").unwrap();println!("Running on  port 3000 ...");for stream in listener.incoming() {let stream = stream.unwrap();println!("Connection established!");}
}

程序创建了一个监听套接字 listener,监听本地环回地址的 3000 端口。incoming() 方法返回一个迭代器,方便处理多个连接。stream 是一个 TcpStream,可以用于读写数据。

打开 tcpclient 成员包下的 main.rs,编写代码:

use std::net::TcpStream;fn main() {let stream = TcpStream::connect("localhost:3000").unwrap();
}

程序作为客户端发起连接,连接到本地环回地址的 3000 端口。

在终端中输入命令: cargo run -p tcpserver,运行服务端进行监听。

在这里插入图片描述

新建一个终端,在新的终端中输入命令: cargo run -p tcpclient,运行客户端发起连接。

在这里插入图片描述

回到服务端,新打印了一条语句:

在这里插入图片描述

说明服务端监听到了来自客户端的请求,并成功建立了连接。

客户端发起连接后,main 函数就执行完了。但 incoming() 方法不会只接收一次连接就关闭,所以服务端要用 Ctrl + C 强制终止程序。

收发数据

TcpStream 实现了 io::Write、io::Read 两个 trait。

打开 tcpserver 成员包下的 main.rs,修改代码:

use std::io::{Read, Write};
use std::net::TcpListener;fn main() {let listener = TcpListener::bind("127.0.0.1:3000").unwrap();println!("Running on  port 3000 ...");for stream in listener.incoming() {let mut stream = stream.unwrap();println!("Connection established!");let mut buffer = [0; 1024];stream.read(&mut buffer).unwrap();stream.write(&mut buffer).unwrap();}
}

服务端建立连接后,读取 stream 中接收到的内容,存储在 buffer 中。再将 buffer 通过 stream 发送给客户端。

这种从客户端读取内容,再原封不动发送给相同客户端的服务端,一般称为回声(echo)服务端。

打开 tcpclient 成员包下的 main.rs,修改代码:

use std::io::{Read, Write};
use std::net::TcpStream;fn main() {let mut stream = TcpStream::connect("localhost:3000").unwrap();stream.write("Hello, World!".as_bytes()).unwrap();let mut buffer = [0; 13];stream.read(&mut buffer).unwrap();println!("Response from server: {:?}", str::from_utf8(&buffer).unwrap());
}

客户端发送一个字符串给 localhost:3000,再从 stream 中读取内容,并打印出来。

和上一小节一样,在终端中输入命令: cargo run -p tcpserver,运行服务端进行监听。新建一个终端,在新的终端中输入命令: cargo run -p tcpclient,运行客户端发起连接。

在这里插入图片描述

在这里插入图片描述

可以看出,服务端监听端口,实现了回声功能。客户端最终接收到了自己发给客户端的信息。

http://www.dtcms.com/a/265487.html

相关文章:

  • Go基础(Gin)
  • Webpack 5 核心机制详解与打包性能优化实践
  • 牛客:HJ16 购物单【01背包】【华为机考】
  • 前端单元测试覆盖率工具有哪些,分别有什么优缺点
  • 在 Sepolia 上使用 Zama fhEVM 构建隐私代币与流动性池:全流程实战指南
  • Android音视频探索之旅 | CMake基础语法 创建支持Ffmpeg的Android项目
  • 【免费.NET方案】CSV到PDF与DataTable的快速转换
  • 音频动态压缩算法曲线实现
  • C++【成员变量、成员函数、this指针】
  • OSPF高级特性之FRR
  • Vue 项目在哪里加载「字典数据」最好
  • 基于 alpine 构建 .net 的基础镜像
  • 开源模型应用落地-让AI更懂你的每一次交互-Mem0集成Qdrant、Neo4j与Streamlit的创新实践(四)
  • Zookeeper 客户端 .net访问框架 ZookeeperNetEx项目开发编译
  • 开源 C# .net mvc 开发(六)特殊控制控制台、周期、邮件编程
  • 深度实战:Ubuntu服务器宕机排查全记录
  • 月付物理服务器租用平台-青蛙云
  • 基于 govaluate 的监控系统中,如何设计灵活可扩展的自定义表达式函数体系
  • npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree
  • Python Set() 完全指南:从入门到精通
  • R语言开发记录,一
  • 前端-HTML-day1
  • Rust Web 全栈开发(二):构建 HTTP Server
  • 主流分布式中间件及其选型
  • locate命令的原理是啥
  • OpenCV CUDA模块设备层-----在GPU 上高效地执行两个 uint 类型值的最大值比较函数vmax2()
  • Frida:配置自动补全 in VSCode
  • 搭建VirtualBox-6+vagrant_2+docker+mysql5.7的步骤
  • 客户案例 | 某新能源车企依托Atlassian工具链+龙智定制开发服务,打造符合ASPICE标准的研发管理体系
  • 云原生系统DOCKER中容器系统搭建