Rust网络编程库deno_net的使用,deno_net提供高性能异步网络通信和TCP/UDP协议支持

Rust网络编程库deno_net的使用

deno_net是一个实现网络API的Rust库,提供高性能异步网络通信和TCP/UDP协议支持。

使用示例

从JavaScript中,包含扩展的源:

import * as webidl from "ext:deno_webidl/00_webidl.js";
import * as net from "ext:deno_net/01_net.js";
import * as tls from "ext:deno_net/02_tls.js";

然后在Rust中提供: deno_net::deno_net::init::<Permissions>(root_cert_store_provider, unsafely_ignore_certificate_errors)

其中:

  • root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>
  • unsafely_ignore_certificate_errors: Option<Vec<String>>
  • Permissions: 实现deno_net::NetPermissions的结构体

RuntimeOptionsextensions字段中

完整Rust示例

use deno_net::deno_net;
use std::sync::Arc;

// 定义权限结构体
struct MyPermissions;

impl deno_net::NetPermissions for MyPermissions {
    // 实现所需的方法...
}

fn main() {
    // 初始化deno_net
    deno_net::init::<MyPermissions>(None, None);
    
    // 这里可以添加网络操作代码
    // 例如创建TCP/UDP服务器或客户端
}

完整示例demo

下面是一个更完整的TCP服务器和客户端示例:

use deno_net::deno_net;
use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

// 定义权限结构体
struct MyPermissions;

impl deno_net::NetPermissions for MyPermissions {
    fn check_net(&self, _host: &str, _port: u16) -> std::io::Result<()> {
        Ok(()) // 允许所有网络访问
    }
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
    // 初始化deno_net
    deno_net::init::<MyPermissions>(None, None);
    
    // 启动TCP服务器
    let server = tokio::spawn(async {
        let listener = deno_net::op_net_listen_tcp("127.0.0.1:8080").await.unwrap();
        println!("Server listening on 127.0.0.1:8080");
        
        let (mut socket, _) = listener.accept().await.unwrap();
        println!("Client connected");
        
        let mut buf = [0; 1024];
        let n = socket.read(&mut buf).await.unwrap();
        println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
        
        socket.write_all(b"Hello from server").await.unwrap();
    });

    // 启动TCP客户端
    let client = tokio::spawn(async {
        tokio::time::sleep(std::time::Duration::from_secs(1)).await;
        
        let mut socket = deno_net::op_net_connect_tcp("127.0.0.1:8080").await.unwrap();
        println!("Connected to server");
        
        socket.write_all(b"Hello from client").await.unwrap();
        
        let mut buf = [0; 1024];
        let n = socket.read(&mut buf).await.unwrap();
        println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
    });

    server.await.unwrap();
    client.await.unwrap();
    
    Ok(())
}

提供的操作

deno_net提供了以下操作,可以通过Deno.ops访问:

网络操作

  • op_net_accept_tcp
  • op_net_accept_unix
  • op_net_connect_tcp
  • op_net_connect_unix
  • op_net_listen_tcp
  • op_net_listen_udp
  • op_net_listen_unix
  • op_net_listen_unixpacket
  • op_net_recv_udp
  • op_net_recv_unixpacket
  • op_net_send_udp
  • op_net_send_unixpacket
  • op_net_connect_tls
  • op_net_listen_tls
  • op_net_accept_tls
  • op_net_join_multi_v4_udp
  • op_net_join_multi_v6_udp
  • op_net_leave_multi_v4_udp
  • op_net_leave_multi_v6_udp
  • op_net_set_multi_loopback_udp
  • op_net_set_multi_ttl_udp

TLS操作

  • op_tls_start
  • op_tls_handshake
  • op_tls_key_null
  • op_tls_key_static
  • op_tls_key_static_from_file
  • op_tls_cert_resolver_create
  • op_tls_cert_resolver_poll
  • op_tls_cert_resolver_resolve
  • op_tls_cert_resolver_resolve_error

其他操作

  • op_node_unstable_net_listen_udp
  • op_dns_resolve
  • op_set_nodelay
  • op_set_keepalive
  • op_node_unstable_net_listen_unixpacket

依赖项

  • deno_web: 由deno_web crate提供
  • deno_fetch: 由deno_fetch crate提供

安装

在项目目录中运行以下Cargo命令:

cargo add deno_net

或在Cargo.toml中添加:

deno_net = "0.204.0"

1 回复

Rust网络编程库deno_net使用指南

deno_net是Deno运行时中的一个高性能网络编程库,提供了异步网络通信能力,支持TCP和UDP协议。它专为高性能I/O操作设计,适合构建网络服务器和客户端应用。

主要特性

  • 异步非阻塞I/O
  • TCP和UDP协议支持
  • 高性能网络通信
  • 与Tokio运行时良好集成
  • 简洁易用的API

基本使用方法

添加依赖

首先在Cargo.toml中添加deno_net依赖:

[dependencies]
deno_net = "0.7"
tokio = { version = "1.0", features = ["full"] }

TCP服务器示例

use deno_net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    println!("TCP server listening on 127.0.0.1:8080");
    
    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(n) if n == 0 => return,
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("Failed to read from socket: {}", e);
                        return;
                    }
                };
                
                println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
                
                if let Err极简风格,注重实用性。

## 完整示例代码

下面是一个结合了TCP服务器和客户端的完整示例:

### TCP服务器 (echo_server.rs)

```rust
use deno_net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 绑定到本地8080端口
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    println!("TCP echo server started on 127.0.0.1:8080");
    
    loop {
        // 接受新连接
        let (mut socket, addr) = listener.accept().await?;
        println!("New connection from: {}", addr);
        
        // 为每个连接生成异步任务
        tokio::spawn(async move {
            let mut buf = [0; 1024];  // 1KB缓冲区
            
            loop {
                // 读取数据
                let n = match socket.read(&mut buf).await {
                    Ok(0) => {  // 连接关闭
                        println!("Connection closed by client: {}", addr);
                        return;
                    }
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("Read error from {}: {}", addr, e);
                        return;
                    }
                };
                
                // 打印接收到的数据
                let received = String::from_utf8_lossy(&buf[..n]);
                println!("Received from {}: {}", addr, received);
                
                // 回写相同数据 (echo)
                if let Err(e) = socket.write_all(&buf[..n]).await {
                    eprintln!("Write error to {}: {}", addr, e);
                    return;
                }
            }
        });
    }
}

TCP客户端 (echo_client.rs)

use deno_net::TcpStream;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 连接到服务器
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
    println!("Connected to server at 127.0.0.1:8080");
    
    // 准备要发送的消息
    let messages = vec![
        "Hello, server!",
        "This is a test message",
        "Another message",
        "quit"  // 特殊命令关闭连接
    ];
    
    for msg in messages {
        // 发送消息
        println!("Sending: {}", msg);
        stream.write_all(msg.as_bytes()).await?;
        
        // 如果是quit命令则退出
        if msg == "quit" {
            println!("Closing connection...");
            break;
        }
        
        // 接收响应
        let mut buf = [0; 1024];
        let n = stream.read(&mut buf).await?;
        let response = String::from_utf8_lossy(&buf[..n]);
        println!("Received echo: {}", response);
        
        // 短暂延迟
        tokio::time::sleep(std::time::Duration::from_millis(500)).await;
    }
    
    Ok(())
}

UDP服务器 (udp_echo_server.rs)

use deno_net::UdpSocket;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 绑定到本地8081端口
    let socket = UdpSocket::bind("127.0.0.1:8081").await?;
    println!("UDP echo server started on 127.0.0.1:8081");
    
    let mut buf = [0; 1024];  // 1KB缓冲区
    
    loop {
        // 接收数据
        let (len, addr) = socket.recv_from(&mut buf).await?;
        let received = String::from_utf8_lossy(&buf[..len]);
        println!("Received from {}: {}", addr, received);
        
        // 如果是quit命令则退出
        if received == "quit" {
            println!("Shutting down server...");
            break;
        }
        
        // 回写相同数据 (echo)
        socket.send_to(&buf[..len], addr).await?;
    }
    
    Ok(())
}

UDP客户端 (udp_echo_client.rs)

use deno_net::UdpSocket;
use tokio::time;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 绑定到随机端口
    let socket = UdpSocket::bind("0.0.0.0:0").await?;
    let server_addr = "127.0.0.1:8081";
    
    // 准备要发送的消息
    let messages = vec![
        "Hello, UDP server!",
        "This is a UDP test",
        "Another UDP message",
        "quit"  // 特殊命令关闭服务器
    ];
    
    for msg in messages {
        // 发送消息
        println!("Sending to {}: {}", server_addr, msg);
        socket.send_to(msg.as_bytes(), server_addr).await?;
        
        // 如果是quit命令则退出
        if msg == "quit" {
            println!("Sending quit command to server...");
            break;
        }
        
        // 接收响应
        let mut buf = [0; 1024];
        let (len, _) = socket.recv_from(&mut buf).await?;
        let response = String::from_utf8_lossy(&buf[..len]);
        println!("Received echo: {}", response);
        
        // 短暂延迟
        time::sleep(time::Duration::from_millis(500)).await;
    }
    
    Ok(())
}

运行说明

  1. 首先启动TCP或UDP服务器
  2. 然后运行对应的客户端
  3. 服务器会打印接收到的消息并回显给客户端
  4. 客户端发送"quit"命令可以关闭连接或服务器

这些示例展示了deno_net的基本用法,包括TCP/UDP通信、异步I/O操作和错误处理。你可以根据实际需求修改和扩展这些代码。

回到顶部