女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Tokio 的基本用法

科技綠洲 ? 來源:TinyZ ? 作者:TinyZ ? 2023-09-19 16:05 ? 次閱讀

Tokio 是一個異步 I/O 框架,它提供了一種高效的方式來編寫異步代碼。它使用 Rust 語言的 Futures 庫來管理異步任務,并使用 Reactor 模式來處理 I/O 事件。

本系列 Tokio 篇將由淺入深的從基礎到實戰,以一個完整的 Rust 語言子系列講述網絡編程

為什么要使用 Tokio?

在 Rust 中,使用異步編程可以提高程序的性能和響應速度,但是異步編程往往需要編寫大量的樣板代碼和復雜的控制流程。Tokio 提供了一種簡單的方式來編寫異步代碼,它使用 Futures 庫來管理異步任務,并提供了一組工具來處理異步 I/O 事件。

如何使用 Tokio?

使用 Tokio 編寫異步代碼需要掌握以下幾個概念:

  • ? Future:表示一個異步任務,可以理解為一個異步函數的返回值;
  • ? Task:表示一個異步任務的執行上下文,可以理解為一個異步函數的執行環境;
  • ? Reactor:表示一個 I/O 事件的處理器,可以理解為一個事件循環;
  • ? Runtime:表示一個異步任務的執行環境,可以理解為一個異步函數的運行時環境。

下面我們將使用 Tokio 編寫一個最基礎的服務器和客戶端程序,以便了解 Tokio 的基本用法。

編寫服務器

我們將編寫一個簡單的 PingPong 服務器,它接收客戶端的 Ping 請求,并返回 Pong 響應。首先,我們需要創建一個異步任務來處理客戶端的請求。我們可以使用 Tokio 提供的async關鍵字來定義一個異步函數:

async fn handle_client(mut stream: TcpStream) - > Result< (), Box< dyn Error >> {
    // ...
}

這個異步函數接收一個TcpStream對象,表示一個客戶端連接。我們可以在函數內部處理客戶端的請求,并返回一個Result對象表示異步任務的執行結果。在處理客戶端請求之前,我們需要先向客戶端發送一個歡迎消息:

async fn handle_client(mut stream: TcpStream) - > Result< (), Box< dyn Error >> {
    println!("new client connected");

    let mut buf = [0; 1024];
    stream.write_all(b"Welcome to the PingPong server!n").await?;

    // ...
}

在發送歡迎消息之后,我們需要不斷地從客戶端讀取數據,并返回 Pong 響應。我們可以使用一個無限循環來實現這個功能:

async fn handle_client(mut stream: TcpStream) - > Result< (), Box< dyn Error >> {
    println!("new client connected");

    let mut buf = [0; 1024];
    stream.write_all(b"Welcome to the PingPong server!n").await?;

    loop {
        let n = stream.read(&mut buf).await?;
        if n == 0 {
            break;
        }
        stream.write_all(b"Pongn").await?;
    }

    println!("client disconnected");
    Ok(())
}

在循環中,我們使用stream.read()方法從客戶端讀取數據,并使用stream.write_all()方法向客戶端發送 Pong 響應。如果客戶端關閉了連接,我們就退出循環并返回Ok(())表示異步任務執行成功。

現在我們已經編寫了一個異步任務來處理客戶端請求,接下來我們需要創建一個 Reactor 來處理 I/O 事件。我們可以使用 Tokio 提供的TcpListener對象來監聽客戶端連接:

#[tokio::main]
async fn main() - > Result< (), Box< dyn Error >> {
    let addr = "127.0.0.1:8080";
    let listener = TcpListener::bind(addr).await?;
    println!("listening on {}", addr);

    loop {
        let (stream, _) = listener.accept().await?;
        tokio::spawn(async move {
            if let Err(e) = handle_client(stream).await {
                eprintln!("error: {}", e);
            }
        });
    }
}

main函數中,我們首先創建一個TcpListener對象來監聽客戶端連接。然后我們使用一個無限循環來等待客戶端連接,并使用listener.accept()方法來接收客戶端連接。當有新的客戶端連接時,我們就創建一個新的異步任務來處理客戶端請求,并使用tokio::spawn()方法將任務提交到 Reactor 中執行。

現在我們已經完成了一個最基礎的 PingPong 服務器,可以使用cargo run命令來運行程序,并使用 telnet 命令來測試服務器:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
     Running `target/debug/pingpong`
listening on 127.0.0.1:8080
$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome to the PingPong server!
ping
Pong
ping
Pong
^]
telnet > quit
Connection closed.

編寫客戶端

現在我們已經編寫了一個最基礎的 PingPong 服務器,接下來我們將編寫一個客戶端程序來連接服務器并發送 Ping 請求。首先,我們需要創建一個異步任務來連接服務器:

async fn connect() - > Result< (), Box< dyn Error >> {
    let addr = "127.0.0.1:8080";
    let mut stream = TcpStream::connect(addr).await?;
    println!("connected to {}", addr);

    // ...
}

這個異步任務使用TcpStream::connect()方法來連接服務器,并返回一個Result對象表示連接結果。在連接成功之后,我們可以向服務器發送一個 Ping 請求:

async fn connect() - > Result< (), Box< dyn Error >> {
    let addr = "127.0.0.1:8080";
    let mut stream = TcpStream::connect(addr).await?;
    println!("connected to {}", addr);

    stream.write_all(b"Pingn").await?;
    let mut buf = [0; 1024];
    let n = stream.read(&mut buf).await?;
    let pong = std::str::from_utf8(&buf[..n])?;
    println!("{}", pong);

    Ok(())
}

在發送 Ping 請求之后,我們使用stream.read()方法從服務器讀取響應,并使用std::str::from_utf8()方法將響應轉換為字符串。最后,我們將響應打印到控制臺上,并返回Ok(())表示異步任務執行成功。

現在我們已經編寫了一個異步任務來連接服務器并發送 Ping 請求,接下來我們需要在main函數中啟動這個任務:

#[tokio::main]
async fn main() - > Result< (), Box< dyn Error >> {
    connect().await?;
    Ok(())
}

現在我們已經完成了一個最基礎的 PingPong 客戶端,可以使用cargo run命令來運行程序,并查看控制臺輸出:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
     Running `target/debug/pingpong`
connected to 127.0.0.1:8080
Pong

完整代碼

最后,我們將完整的服務器和客戶端代碼放在一起,以便讀者參考:

use std::error::Error;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};

async fn handle_client(mut stream: TcpStream) - > Result< (), Box< dyn Error >> {
    println!("new client connected");

    let mut buf = [0; 1024];
    stream.write_all(b"Welcome to the PingPong server!n").await?;

    loop {
        let n = stream.read(&mut buf).await?;
        if n == 0 {
            break;
        }
        stream.write_all(b"Pongn").await?;
    }

    println!("client disconnected");
    Ok(())
}

#[tokio::main]
async fn main() - > Result< (), Box< dyn Error >> {
    let addr = "127.0.0.1:8080";
    let listener = TcpListener::bind(addr).await?;
    println!("listening on {}", addr);

    loop {
        let (stream, _) = listener.accept().await?;
        tokio::spawn(async move {
            if let Err(e) = handle_client(stream).await {
                eprintln!("error: {}", e);
            }
        });
    }
}

async fn connect() - > Result< (), Box< dyn Error >> {
    let addr = "127.0.0.1:8080";
    let mut stream = TcpStream::connect(addr).await?;
    println!("connected to {}", addr);

    stream.write_all(b"Pingn").await?;
    let mut buf = [0; 1024];
    let n = stream.read(&mut buf).await?;
    let pong = std::str::from_utf8(&buf[..n])?;
    println!("{}", pong);

    Ok(())
}

#[tokio::main]
async fn main() - > Result< (), Box< dyn Error >> {
    connect().await?;
    Ok(())
}

總結

通過本文的介紹,我們了解了 Tokio 的基本用法,并編寫了一個最基礎的 PingPong 服務器和客戶端程序。Tokio 提供了一種簡單的方式來編寫異步代碼,可以幫助我們提高程序的性能和響應速度。在實際開發中,我們可以根據需要使用 Tokio 提供的各種工具來編寫更加復雜的異步程序。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 程序
    +關注

    關注

    117

    文章

    3820

    瀏覽量

    82379
  • 代碼
    +關注

    關注

    30

    文章

    4886

    瀏覽量

    70232
  • 網絡編程
    +關注

    關注

    0

    文章

    72

    瀏覽量

    10519
  • Tokio
    +關注

    關注

    0

    文章

    12

    瀏覽量

    118
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    SQLx的基礎用法和進階用法

    SQLx是一個Rust語言的異步SQL數據庫訪問庫,支持多種數據庫,包括PostgreSQL、MySQL、SQLite等。本教程將以SQLite為例,介紹SQLx的基礎用法和進階用法。 基礎用法
    的頭像 發表于 09-19 14:29 ?2811次閱讀

    SQLx在Rust語言中的基礎用法和進階用法

    SQLx是一個Rust語言的異步SQL執行庫,它支持多種數據庫,包括MySQL、PostgreSQL、SQLite等。本教程將以MySQL數據庫為例,介紹SQLx在Rust語言中的基礎用法和進階用法
    的頭像 發表于 09-19 14:32 ?5955次閱讀

    Stream模塊的基礎用法和進階用法

    在 Rust 語言中,Tokio 是一個非常流行的異步編程框架。它提供了一系列的模塊,其中最常用的就是 Stream 模塊。Stream 模塊允許我們以異步的方式處理數據流,這在很多情況下非常
    的頭像 發表于 09-19 15:33 ?1488次閱讀

    什么是Tokio模塊 Channel?

    Rust 語言是一種系統級編程語言,它具有強類型和內存安全性。Rust 語言中的 Tokio 模塊是一個異步編程庫,它提供了一種高效的方式來處理異步任務。其中,channel 是 Tokio 模塊中
    的頭像 發表于 09-19 15:57 ?1230次閱讀

    AsyncRead和AsyncWrite 模塊進階用法示例

    們。 基礎用法 從文件中讀取數據 use tokio::fs::File; use tokio::io::{ self , AsyncReadExt}; #[tokio:
    的頭像 發表于 09-20 11:41 ?1101次閱讀

    狀態機原理及用法

    狀態機原理及用法狀態機原理及用法狀態機原理及用法
    發表于 03-15 15:25 ?0次下載

    使用tokio實現一個簡單的Client和Server通訊模型

    本系列是關于用Rust構建一個KV Server的系列文章,內容包括用tokio做底層異步網絡通訊、使用toml文件做配置、protobuf做傳輸協議、內存/RockDB做數據存儲、事件通知、優雅關機、并發連接限制及測量監控等。
    的頭像 發表于 09-09 09:45 ?2578次閱讀

    WasmEdge增加了Tokio支持

    看:https://wasmer.io/posts/wasmer-takes-webassembly-libraries-manistream-with-wai WasmEdge增加了Tokio 支持
    的頭像 發表于 12-05 11:55 ?1010次閱讀

    Tokio中hang死所有worker的方法

    原因是 tokio 里的待執行 task 不是簡單的放到一個 queue 里,除了 runtime 內共享的,可被每個 worker 消費的run_queue[2],每個 worker 還有一個自己的 lifo_slot[3],只存儲一個最后被放入的 task (目的是減小調度延遲)。
    的頭像 發表于 02-03 16:26 ?1157次閱讀

    文盤Rust -- 用Tokio實現簡易任務池

    59執行完后面就沒有輸出了,如果把max_task設置為2,情況會好一點,但是也沒有執行完所有的異步操作,也就是說在資源不足的情況下,Tokio會拋棄某些任務,這不符合我們的預期。
    的頭像 發表于 04-09 10:24 ?1521次閱讀

    Tokio 模塊的優雅停機機制

    在進行高并發、網絡編程時,優雅停機是一個非常重要的問題。在 Rust 語言中,Tokio 是一個非常流行的異步編程框架,它提供了一些優雅停機的機制,本文將圍繞 Tokio 模塊的優雅停機進行詳細
    的頭像 發表于 09-19 15:26 ?879次閱讀

    如何使用Tokio 和 Tracing模塊構建異步的網絡應用程序

    在 Rust 語言中,Tokio 是一個非常流行的異步運行時,它提供了高效的異步 I/O 操作和任務調度。而 Tracing 則是一個用于應用程序跟蹤的框架,它可以幫助我們理解應用程序的行為和性能
    的頭像 發表于 09-19 15:29 ?980次閱讀

    基于select!宏的進階用法

    Tokio 是一個基于 Rust 語言的異步編程框架,它提供了一組工具和庫,使得異步編程變得更加容易和高效。其中最重要的組件之一就是 select!宏。 select!宏是 Tokio 中的一個核心
    的頭像 發表于 09-19 15:35 ?955次閱讀

    如何使用 Tokio 模塊的Channel

    Channel 是一種在多線程環境下進行通信的機制,可以讓線程之間互相發送消息和共享數據。Rust 語言中的 Tokio 模塊提供了一種異步的 Channel 實現,使得我們可以在異步程序中方
    的頭像 發表于 09-19 15:38 ?900次閱讀

    tokio模塊channel中的使用場景和優缺點

    Rust 語言的 tokio 模塊提供了一種高效的異步編程方式,其中的 channel 模塊是其核心組件之一。本教程將介紹 tokio 模塊 channel 的除了上文提到的 mspc
    的頭像 發表于 09-19 15:54 ?1134次閱讀