<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Blog by AlanKSorata</title><link>https://AlanKSorata.github.io</link><description>Casually</description><copyright>Blog by AlanKSorata</copyright><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><image><url>https://github.githubassets.com/favicons/favicon.svg</url><title>avatar</title><link>https://AlanKSorata.github.io</link></image><lastBuildDate>Sat, 04 Apr 2026 08:26:02 +0000</lastBuildDate><managingEditor>Blog by AlanKSorata</managingEditor><ttl>60</ttl><webMaster>Blog by AlanKSorata</webMaster><item><title>（个人向）如何以Rust的眼光重学C++</title><link>https://AlanKSorata.github.io/post/%EF%BC%88-ge-ren-xiang-%EF%BC%89-ru-he-yi-Rust-de-yan-guang-zhong-xue-C%2B%2B.html</link><description>## 一直以来

&gt; 一直以来，我陷入了一段离奇魔幻的经历，因为不堪C++那庞大的知识体系，当然不乏来自各个平台上声声相传的消极评价，让我对C++生不起一丝好学的情绪。</description><guid isPermaLink="true">https://AlanKSorata.github.io/post/%EF%BC%88-ge-ren-xiang-%EF%BC%89-ru-he-yi-Rust-de-yan-guang-zhong-xue-C%2B%2B.html</guid><pubDate>Sat, 04 Apr 2026 08:23:52 +0000</pubDate></item><item><title>Rust Web（三）—— 通过sqlx连接数据库(MySQL)</title><link>https://AlanKSorata.github.io/post/Rust%20Web%EF%BC%88-san-%EF%BC%89%E2%80%94%E2%80%94%20-tong-guo-sqlx-lian-jie-shu-ju-ku-%28MySQL%29.html</link><description>&lt;div id='article_content' class='article_content clearfix'&gt;
        &lt;link rel='stylesheet' href='https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css'&gt;
        &lt;link rel='stylesheet' href='https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-a50b13a894.css'&gt;
                &lt;div id='content_views' class='htmledit_views tomorrow-night'&gt;
                    &lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在学习了前辈所演示的 PostgreSQL连接方式后所进行的尝试；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;通过这次尝试也能够进一步学习连接MySQL的其中一种方式；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;除本文所使用的&lt;code&gt;sqlx&lt;/code&gt;连接方法外，还有其他的方式，诸如&lt;code&gt;diesel&lt;/code&gt;，以后有机会在进行实践；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h2 id='Rust%20Web%EF%BC%88%E4%B8%89%EF%BC%89%E2%80%94%E2%80%94%20%E9%80%9A%E8%BF%87sqlx%E8%BF%9E%E6%8E%A5%E6%95%B0%E6%8D%AE%E5%BA%93(MySQL)'&gt;&lt;a name='t0'&gt;&lt;/a&gt;&lt;span class='words-blog hl-git-1' data-tit='Rust' data-pretit='rust'&gt;Rust&lt;/span&gt; &lt;span style='color: #3391E5' class='new-words-blog' data-href='https://ai.csdn.net/?openMirrorId=img697851c35348ba493b73ffb8&amp;amp;utm_source=xtai_slb_kw_0310' data-report-click='{&amp;quot;spm&amp;quot;:&amp;quot;3001.11407&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://ai.csdn.net/?openMirrorId=img697851c35348ba493b73ffb8&amp;amp;utm_source=xtai_slb_kw_0310&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;wordId&amp;quot;:138473,&amp;quot;businessId&amp;quot;:2,&amp;quot;word&amp;quot;:&amp;quot;Web&amp;quot;,&amp;quot;blogTemplateId&amp;quot;:-1}}' data-report-query='spm=1001.2101.3001.11407' data-tit='Web'&gt;
              Web 
              &lt;/span&gt;（三）—— 通过sqlx连接数据库(MySQL)&lt;/h2&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%B8%80%E3%80%81%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87'&gt;&lt;a name='t1'&gt;&lt;/a&gt;一、环境准备&lt;/h3&gt; 
&lt;hr&gt;
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E9%A1%B9%E7%9B%AE%E5%88%9B%E5%BB%BA'&gt;&lt;a name='t2'&gt;&lt;/a&gt;&lt;span class='words-blog hl-git-1' data-tit='项目' data-pretit='项目'&gt;项目&lt;/span&gt;创建&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在自己选择的目录下，创建一个(子)项目，此处命名为 &lt;code&gt;db&lt;/code&gt;；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;在新建项目的 &lt;code&gt;Cargo.toml&lt;/code&gt; 文件内，添加所需要的依赖，具体如下：&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 

```toml
[package]
name = 'db'
version = '0.1.0'
edition = '2021'
​
[dependencies]
actix-rt='2.7.0'
actix-web='4.1.0'
dotenv = '0.15.0'
chrono = {version = '0.4.19', features = ['serde']}
serde = {version = '1.0.140', features = ['derive']}
sqlx = {version = '0.6.0', default_features = false, features = [
    'mysql',
    'runtime-tokio-rustls',
    'macros',
    'chrono',
]}
```

&lt;p&gt;&lt;strong&gt;注意:&lt;/strong&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在添加 &lt;code&gt;crate&lt;/code&gt; 时，注意使用版本要&lt;strong&gt;相互兼容&lt;/strong&gt;，否则会出现编译警告：&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;The following warnings were discovered during the build. These warnings are an indication that the packages contain code that will become an error in a future release of Rust. These warnings typically cover changes to close soundness problems, unintended or undocumented behavior, or critical problems that cannot be fixed in a backwards-compatible fashion, and are not expected to be in wide use.&lt;/p&gt; 
 &lt;p&gt;Each warning should contain a link for more information on what the warning means and how to resolve it.&lt;/p&gt; 
 &lt;p&gt;To solve this problem, you can try the following approaches:&lt;/p&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;Some affected dependencies have newer versions available. You may want to &lt;strong&gt;consider updating them to a newer version&lt;/strong&gt; to see if the issue has been fixed.&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;&lt;strong&gt;winapi v0.2.8&lt;/strong&gt; has the following newer versions available: 0.3.0, 0.3.1, 0.3.2, 0.3.3, 0.3.4, 0.3.5, 0.3.6, 0.3.7, 0.3.8, 0.3.9&lt;/p&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;If the issue is not solved by updating the dependencies, a fix has to be implemented by those dependencies. You can help with that by notifying the maintainers of this problem (e.g. by creating a bug report) or by proposing a fix to the maintainers (e.g. by creating a pull request):&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;winapi@0.2.8&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;Repository: &lt;a href='https://github.com/retep998/winapi-rs' title='GitHub - retep998/winapi-rs: Rust bindings to Windows API'&gt;GitHub - retep998/winapi-rs: Rust bindings to Windows API&lt;/a&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;Detailed warning command: &lt;code&gt;cargo report future-incompatibilities --id 1 --package winapi@0.2.8&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; &lt;p&gt;If waiting for an upstream fix is not an option, you can use the &lt;code&gt;[patch]&lt;/code&gt; section in &lt;code&gt;Cargo.toml&lt;/code&gt; to use your own version of the dependency. For more information, see: &lt;a href='https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html#the-patch-section' title='Overriding Dependencies - The Cargo Book' rel='nofollow'&gt;Overriding Dependencies - The Cargo Book&lt;/a&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;具体需要访问&lt;code&gt;crates.io&lt;/code&gt; 来查看合适的版本；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;而在&lt;strong&gt;版本兼容&lt;/strong&gt;的的情况下，呈现的是以下结果：&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='194' src='https://i-blog.csdnimg.cn/blog_migrate/8eedc28994dc7ed1a49121a643a80413.png' width='897'&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h4 id='%E8%BF%9E%E6%8E%A5%E8%AF%B7%E6%B1%82'&gt;&lt;a name='t3'&gt;&lt;/a&gt;连接请求&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在&lt;strong&gt;根项目&lt;/strong&gt;的目录下，新建名为 &lt;code&gt;.env&lt;/code&gt; 的文件，在文件内写入请求 URL;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;由于笔者所创建的项目是一个子项目，因此其位置位于所在&lt;strong&gt;根项目&lt;/strong&gt;的目录之下；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 

```bash
DATABASE_URL=mysql://{user}:{password}@{IP}:{port}/{database name}
```

&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%BA%8C%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93%E5%87%86%E5%A4%87'&gt;&lt;a name='t4'&gt;&lt;/a&gt;二、&lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;数据库\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='数据库' data-pretit='数据库'&gt;数据库&lt;/span&gt;准备&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;笔者在此处选择的是过去在名为 &lt;code&gt;test&lt;/code&gt;的数据库中的 &lt;code&gt;tt1&lt;/code&gt;表；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;内容如下：&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='302' src='https://i-blog.csdnimg.cn/blog_migrate/6dc64f41087964b4394c2540bb08573b.png' width='597'&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%B8%89%E3%80%81%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0'&gt;&lt;a name='t5'&gt;&lt;/a&gt;三、功能实现&lt;/h3&gt; 
&lt;hr&gt;
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E8%AF%B4%E6%98%8E'&gt;&lt;a name='t6'&gt;&lt;/a&gt;说明&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;首先简要说明一下本文所涉及 &lt;strong&gt;MySQL&lt;/strong&gt;连接调用的 API&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;strong&gt;MySqlPoolOptions&lt;/strong&gt;&lt;/p&gt; 
     &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;strong&gt;new()&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='187' src='https://i-blog.csdnimg.cn/blog_migrate/726adb2246ace6e44447f0f03d561d29.png' width='911'&gt;&lt;/p&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='219' src='https://i-blog.csdnimg.cn/blog_migrate/5081a09506aafcab56ae2418bc73c4a8.png' width='1200'&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3'&gt;参考文档&lt;/h4&gt; 
&lt;p&gt;&lt;a class='has-card' href='https://docs.rs/sqlx/0.6.0/sqlx/mysql/index.html' title='sqlx::mysql - Rust' rel='nofollow'&gt;&lt;span class='link-card-box'&gt;&lt;span class='link-title'&gt;sqlx::mysql - Rust&lt;/span&gt;&lt;span class='link-desc'&gt;MySQL database driver.&lt;/span&gt;&lt;span class='link-link'&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0'&gt;代码实现&lt;/h4&gt;

```rust
// extern crate chrono;
extern crate dotenv;
extern crate sqlx;
​
// use chrono::NaiveDateTime;
use dotenv::dotenv;
use sqlx::mysql::MySqlPoolOptions;
use std::env;
use std::io;
​
#[derive(Debug)]
pub struct Info {
    pub ind: i32, // 数据库中将此字段设置为了主键
    pub email: Option&lt;String&gt;, // 使用Option来处理潜在的空值情况
    pub uid: Option&lt;i32&gt;,
    pub reg_time: Option&lt;i32&gt;,
}
​
#[actix_rt::main]
async fn main() -&gt; io::Result&lt;()&gt; {
    dotenv().ok(); // 检测并读取.env文件中的内容，若不存在也会跳过异常
​
    let database_url = env::var('DATABASE_URL')
        .expect('Not configured in .env');
​
    let db_pool = MySqlPoolOptions::new()
        .connect(&amp;database_url)
        .await
        .unwrap();
​
    let tt1_rows = sqlx::query!(
        r#'select ind,email,uid,regtime from tt1 where ind = ?'#,
        6
    )
        .fetch_all(&amp;db_pool)
        .await
        .unwrap();
​
    let mut tt1_list = vec![];
    for row in tt1_rows {
        tt1_list.push(Info {
            ind: row.ind.unwrap(),
            email: row.email,
            uid: row.uid,
            reg_time: row.regtime,
        })
    }
    println!('Info = {:?}', tt1_list);
    Ok(())
}
```

&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E8%BF%90%E8%A1%8C%E6%95%88%E6%9E%9C'&gt;&lt;a name='t9'&gt;&lt;/a&gt;运行效果&lt;/h4&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='245' src='https://i-blog.csdnimg.cn/blog_migrate/e40fb26768776491c1b2a0c2e2d1eac9.png' width='922'&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p style='text-align:center;'&gt;&lt;strong&gt;每一个不曾起舞的日子，都是对生命的辜负。</description><guid isPermaLink="true">https://AlanKSorata.github.io/post/Rust%20Web%EF%BC%88-san-%EF%BC%89%E2%80%94%E2%80%94%20-tong-guo-sqlx-lian-jie-shu-ju-ku-%28MySQL%29.html</guid><pubDate>Mon, 30 Mar 2026 03:16:21 +0000</pubDate></item><item><title>Rust Web（二）—— 自建HTTP Server</title><link>https://AlanKSorata.github.io/post/Rust%20Web%EF%BC%88-er-%EF%BC%89%E2%80%94%E2%80%94%20-zi-jian-HTTP%20Server.html</link><description>&lt;div id='article_content' class='article_content clearfix'&gt;
        &lt;link rel='stylesheet' href='https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css'&gt;
        &lt;link rel='stylesheet' href='https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-a50b13a894.css'&gt;
                &lt;div id='content_views' class='htmledit_views tomorrow-night'&gt;
                    &lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt;对于Rust基础以及HTTP原理，需要读者有所认识；&lt;/li&gt;&lt;li&gt;本文的设计思路也可以自行设计扩展进而发展成更完整的方案；&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt;  
&lt;p&gt;&lt;/p&gt; 
&lt;h2 id='Rust%20Web%EF%BC%88%E4%BA%8C%EF%BC%89%E2%80%94%E2%80%94%20%E8%87%AA%E5%BB%BAHTTP%20Server'&gt;&lt;a name='t0'&gt;&lt;/a&gt;&lt;span class='words-blog hl-git-1' data-tit='Rust' data-pretit='rust'&gt;Rust&lt;/span&gt; &lt;span style='color: #3391E5' class='new-words-blog' data-href='https://ai.csdn.net/?openMirrorId=img697851c35348ba493b73ffb8&amp;amp;utm_source=xtai_slb_kw_0310' data-report-click='{&amp;quot;spm&amp;quot;:&amp;quot;3001.11407&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://ai.csdn.net/?openMirrorId=img697851c35348ba493b73ffb8&amp;amp;utm_source=xtai_slb_kw_0310&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;wordId&amp;quot;:138473,&amp;quot;businessId&amp;quot;:2,&amp;quot;word&amp;quot;:&amp;quot;Web&amp;quot;,&amp;quot;blogTemplateId&amp;quot;:-1}}' data-report-query='spm=1001.2101.3001.11407' data-tit='Web'&gt;
              Web 
              &lt;/span&gt;（二）—— 自建HTTP Server&lt;/h2&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%B8%80%E3%80%81%E9%A1%B9%E7%9B%AE%E5%88%9B%E5%BB%BA'&gt;&lt;a name='t1'&gt;&lt;/a&gt;一、项目创建&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在自定的目录下，创建两个子项目目录&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;httpserver&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;http&lt;/code&gt;&lt;/p&gt; 
     &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;http&lt;/code&gt; 为·&lt;code&gt;lib&lt;/code&gt; 库，故命令中添加 &lt;code&gt;--lib&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;img alt='' height='739' src='https://i-blog.csdnimg.cn/blog_migrate/17695a088fb8a4edb8c4093d2e5959fc.png' width='1200'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在根项目的 &lt;code&gt;Cargo.toml&lt;/code&gt;文件中添加这两个子项目&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;img alt='' height='288' src='https://i-blog.csdnimg.cn/blog_migrate/07f1339379b2fbfd61b9d3f03c005414.png' width='740'&gt;&lt;/p&gt;  
&lt;p&gt;&lt;/p&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;进入 &lt;code&gt;http&lt;/code&gt; 子项目，在 &lt;code&gt;src/lib.rs&lt;/code&gt; 内写入公共模块 &lt;code&gt;pub mod httprequest;&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;在同级 &lt;code&gt;src&lt;/code&gt; 目录下新建：&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;httprequest.rs&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;httpresponse.rs&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='88' src='https://i-blog.csdnimg.cn/blog_migrate/7843110fa52fcdee45f6111442b1cd57.png' width='489'&gt;&lt;/p&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='189' src='https://i-blog.csdnimg.cn/blog_migrate/5ff95760f034799bfb048026c2272e34.png' width='348'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%BA%8C%E3%80%81%E8%A7%A3%E6%9E%90HTTP%E8%AF%B7%E6%B1%82'&gt;&lt;a name='t2'&gt;&lt;/a&gt;二、解析&lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;HTTP请求\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='HTTP请求' data-pretit='http请求'&gt;HTTP请求&lt;/span&gt;&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在 &lt;code&gt;httprequest.rs&lt;/code&gt; 中，先尝试实现 枚举 &lt;code&gt;Method&lt;/code&gt;，并进行一次测试&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 

```rust
#[derive(Debug, PartialEq)]
pub enum Method {
    Get,
    Post,
    Uninitialized,
}
​
impl From&lt;&amp;str&gt; for Method {
    fn from(s: &amp;str) -&gt; Method {
        match s {
            'GET' =&gt; Method::Get,
            'POST' =&gt; Method::Post,
            _ =&gt; Method::Uninitialized,
        }
    }
}
​
#[cfg(test)]
mod tests {
    use super::*;
​
    #[test]
    fn test_method_into() {
        let m: Method = 'GET'.into();
        assert_eq!(m, Method::Get);
    }
}
``` 

&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E6%B5%8B%E8%AF%95%E7%A4%BA%E4%BE%8B'&gt;&lt;a name='t3'&gt;&lt;/a&gt;测试示例&lt;/h4&gt; 
&lt;p&gt;&lt;img alt='' height='439' src='https://i-blog.csdnimg.cn/blog_migrate/91edc4ef1096b69a7cdbeb96990fee5e.png' width='1200'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E5%85%A8%E9%83%A8%E5%AE%9E%E7%8E%B0'&gt;&lt;a name='t4'&gt;&lt;/a&gt;全部实现&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;依照HTTP协议原理以及Rust本身的特性，先实现 &lt;code&gt;http&lt;/code&gt; 库内的内容；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;httprequest.rs&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 

```rust
use std::collections::HashMap;
​
#[derive(Debug, PartialEq)]
pub enum Method {
    Get,
    Post,
    Uninitialized,
}
​
impl From&lt;&amp;str&gt; for Method {
    fn from(s: &amp;str) -&gt; Method {
        match s {
            'GET' =&gt; Method::Get,
            'POST' =&gt; Method::Post,
            _ =&gt; Method::Uninitialized,
        }
    }
}
​
#[derive(Debug, PartialEq)]
pub enum Version {
    V11,
    V20,
    Uninitialized,
}
​
impl From&lt;&amp;str&gt; for Version {
    fn from(s: &amp;str) -&gt; Version {
        match s {
            'HTTP/1.1' =&gt; Version::V11,
            'HTTP/2.0' =&gt; Version::V20,
            _ =&gt; Version::Uninitialized,
        }
    }
}
​
#[derive(Debug, PartialEq)]
pub enum Resource {
    Path(String),
}
​
#[derive(Debug)]
pub struct HttpRequest {
    pub method: Method,
    pub version: Version,
    pub resource: Resource,
    pub headers: HashMap&lt;String, String&gt;,
    pub msg_body: String,
}
​
impl From&lt;String&gt; for HttpRequest {
    fn from(req: String) -&gt; Self {
        let mut parsed_method = Method::Uninitialized;
        let mut parsed_version = Version::V11;
        let mut parsed_resource = Resource::Path(''.to_string());
        let mut parsed_headers = HashMap::new();
        let mut parsed_msg_body = '';
​
        for line in req.lines() {
            if line.contains('HTTP') {
                let (method, resource, version) = process_req_line(line);
                parsed_method = method;
                parsed_resource = resource;
                parsed_version = version;
            } else if line.contains(':') {
                let (key, value) = process_header_line(line);
                parsed_headers.insert(key, value);
            } else if line.len() == 0 {
                // No operation
            } else {
                parsed_msg_body = line;
            }
        }
         HttpRequest {
                method: parsed_method,
                resource: parsed_resource,
                version: parsed_version,
                headers: parsed_headers,
                msg_body: parsed_msg_body.to_string(),
            }
    }
}
​
fn process_req_line(s: &amp;str) -&gt; (Method, Resource, Version) {
    let mut words = s.split_whitespace();
    let method = words.next().unwrap();
    let resource = words.next().unwrap();
    let version = words.next().unwrap();
​
    (
        method.into(),
        Resource::Path(resource.to_string()),
        version.into()
    )
}
​
fn process_header_line(s: &amp;str) -&gt; (String, String) {
    let mut header_items = s.split(':');
    let mut key = String::from('');
    let mut value = String::from('');
    if let Some(k) = header_items.next() {
        key = k.to_string();
    }
    if let Some(v) = header_items.next() {
        value = v.to_string();
    }
    (key, value)
}
​
#[cfg(test)]
mod tests {
    use super::*;
​
    #[test]
    fn test_method_into() {
        let m: Method = 'GET'.into();
        assert_eq!(m, Method::Get);
    }
​
    #[test]
    fn test_version_into() {
        let v: Version = 'HTTP/1.1'.into();
        assert_eq!(v, Version::V11);
    }
​
    #[test]
    fn test_read_http() {
        let s: String = String::from('GET /index HTTP/1.1\r\n\
        Host: localhost\r\n\
        User-Agent: Curl/7.64.1\r\n\
        Accept: */*\r\n\r\n');
        let mut headers_expected = HashMap::new();
        headers_expected.insert('Host'.into(), ' localhost'.into());
        headers_expected.insert('User-Agent'.into(), ' Curl/7.64.1'.into());
        headers_expected.insert('Accept'.into(), ' */*'.into());
        let req: HttpRequest = s.into();
​
        assert_eq!(Method::Get, req.method);
        assert_eq!(Resource::Path('/index'.to_string()), req.resource);
        assert_eq!(Version::V11, req.version);
        assert_eq!(headers_expected, req.headers);
    }
}
```

&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E6%B5%8B%E8%AF%95'&gt;&lt;a name='t5'&gt;&lt;/a&gt;测试&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;测试结果&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='616' src='https://i-blog.csdnimg.cn/blog_migrate/22a77ea9ae453fc54a8764b82e7eaea7.png' width='1200'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;编写过程中以下&lt;strong&gt;问题&lt;/strong&gt;值得注意&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;测试请求中的大小写要严格区分；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;由于请求头部仅以&lt;strong&gt;冒号&lt;/strong&gt;分割，因此值 &lt;code&gt;value&lt;/code&gt; 内的空格不能忽略，或者进行进一步优化；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%B8%89%E3%80%81%E6%9E%84%E5%BB%BAHTTP%E5%93%8D%E5%BA%94'&gt;&lt;a name='t6'&gt;&lt;/a&gt;三、构建&lt;span style='color: #FC5531' class='new-words-blog' data-href='https://so.csdn.net/so/search?q=http' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;3001.11407&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://so.csdn.net/so/search?q=http&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;wordId&amp;quot;:26,&amp;quot;businessId&amp;quot;:1,&amp;quot;word&amp;quot;:&amp;quot;http&amp;quot;,&amp;quot;blogTemplateId&amp;quot;:-1}}' data-report-click='{&amp;quot;spm&amp;quot;:&amp;quot;3001.11407&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://so.csdn.net/so/search?q=http&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;wordId&amp;quot;:26,&amp;quot;businessId&amp;quot;:1,&amp;quot;word&amp;quot;:&amp;quot;http&amp;quot;,&amp;quot;blogTemplateId&amp;quot;:-1}}' data-report-query='spm=1001.2101.3001.11407' data-tit='HTTP'&gt;
              HTTP &lt;i style='background-image: url(https://i-operation.csdnimg.cn/images/e7c3df7a602f4267be505af7ecfc3f88.png);' alt='HTTP' class='words-blog-icon'&gt;&lt;/i&gt;
              &lt;/span&gt;响应&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;以下为自建库的&lt;strong&gt;响应构建&lt;/strong&gt;部分；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;httpresponse.rs&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 

```rust
use std::collections::HashMap;
use std::io::{Result, Write};
​
// 当涉及到成员变量中有引用类型，就需要引入生命周期
#[derive(Debug, PartialEq, Clone)]
pub struct HttpResponse&lt;'a&gt; {
    version: &amp;'a str,
    status_code: &amp;'a str,
    status_text: &amp;'a str,
    headers: Option&lt;HashMap&lt;&amp;'a str, &amp;'a str&gt;&gt;,
    body: Option&lt;String&gt;,
}
​
impl&lt;'a&gt; Default for HttpResponse&lt;'a&gt; {
    fn default() -&gt; Self {
        Self {
            version: 'HTTP/1.1'.into(),
            status_code: '200'.into(),
            status_text: 'OK'.into(),
            headers: None,
            body: None,
        }
    }
}
​
impl&lt;'a&gt; From&lt;HttpResponse&lt;'a&gt;&gt; for String {
    fn from(res: HttpResponse) -&gt; String {
        let res1 = res.clone();
        format!(
            '{} {} {}\r\n{}Content-Length: {}\r\n\r\n{}',
            &amp;res1.version(),
            &amp;res1.status_code(),
            &amp;res1.status_text(),
            &amp;res1.headers(),
            &amp;res.body.unwrap().len(),
            &amp;res1.body() //
        )
    }
}
​
impl&lt;'a&gt; HttpResponse&lt;'a&gt; {
    pub fn new(
        status_code: &amp;'a str,
        headers: Option&lt;HashMap&lt;&amp;'a str, &amp;'a str&gt;&gt;,
        body: Option&lt;String&gt;
    ) -&gt; HttpResponse&lt;'a&gt; {
        let mut response: HttpResponse&lt;'a&gt; = HttpResponse::default(); // mut
        if status_code != '200' {
            response.status_code = status_code.into();
        };
        response.headers = match &amp;headers {
            Some(_h) =&gt; headers,
            None =&gt; {
                let mut h = HashMap::new();
                h.insert('Content-Type', 'text/html');
                Some(h)
            }
        };
        response.status_text = match response.status_code {
            '200' =&gt; 'OK'.into(),
            '400' =&gt; 'Bad Request'.into(),
            '404' =&gt; 'Not Found'.into(),
            '500' =&gt; 'Internal Server Error'.into(),
            _ =&gt; 'Not Found'.into(), //
        };
​
        response.body = body;
        response
    }
​
    pub fn send_response(&amp;self, write_stream: &amp;mut impl Write) -&gt; Result&lt;()&gt; {
        let res = self.clone();
        let response_string: String = String::from(res); // from trait
        let _ = write!(write_stream, '{}', response_string);
​
        Ok(())
    }
​
    fn version(&amp;self) -&gt; &amp;str {
        self.version
    }
​
    fn status_code(&amp;self) -&gt; &amp;str {
        self.status_code
    }
​
    fn status_text(&amp;self) -&gt; &amp;str {
        self.status_text
    }
​
    fn headers(&amp;self) -&gt; String {
        let map: HashMap&lt;&amp;str, &amp;str&gt; = self.headers.clone().unwrap();
        let mut header_string: String = ''.into();
        for (k, v) in map.iter() {
            header_string = format!('{}{}:{}\r\n', header_string, k, v);
        }
        header_string
    }
​
    pub fn body(&amp;self) -&gt; &amp;str {
        match &amp;self.body {
            Some(b) =&gt; b.as_str(),
            None =&gt; '',
        }
    }
}
​
#[cfg(test)]
mod tests {
    use super::*;
​
    #[test]
    fn test_response_struct_creation_200() {
        let response_actual = HttpResponse::new(
            '200',
            None,
            Some('nothing for now'.into()),
        );
        let response_expected = HttpResponse {
            version: 'HTTP/1.1',
            status_code: '200',
            status_text: 'OK',
            headers: {
                let mut h = HashMap::new();
                h.insert('Content-Type', 'text/html');
                Some(h)
            },
            body: Some('nothing for now'.into()),
        };
​
        assert_eq!(response_actual, response_expected);
    }
​
    #[test]
    fn test_response_struct_creation_404() {
        let response_actual = HttpResponse::new(
            '404',
            None,
            Some('nothing for now'.into()),
        );
        let response_expected = HttpResponse {
            version: 'HTTP/1.1',
            status_code: '404',
            status_text: 'Not Found',
            headers: {
                let mut h = HashMap::new();
                h.insert('Content-Type', 'text/html');
                Some(h)
            },
            body: Some('nothing for now'.into()),
        };
​
        assert_eq!(response_actual, response_expected);
    }
​
    #[test]
    fn test_http_response_creation() {
        let response_expected = HttpResponse {
            version: 'HTTP/1.1',
            status_code: '404',
            status_text: 'Not Found',
            headers: {
                let mut h = HashMap::new();
                h.insert('Content-Type', 'text/html');
                Some(h)
            },
            body: Some('nothing for now'.into()),
        };
        let http_string: String = response_expected.into();
        let actual_string: String =
            'HTTP/1.1 404 Not Found\r\n\
            Content-Type:text/html\r\n\
            Content-Length: 15\r\n\r\n\
            nothing for now'.into(); // 此处注意Content-Length值
​
        assert_eq!(http_string, actual_string);
    }
}
```

&lt;p&gt;&lt;/p&gt; 
&lt;h4&gt;&lt;a name='t7'&gt;&lt;/a&gt;测试&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;测试结果&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;img alt='' height='771' src='https://i-blog.csdnimg.cn/blog_migrate/ed19ef80746a04a186d9c7174391e47d.png' width='1198'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;其中需要留意的点位&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;在实现 &lt;code&gt;String&lt;/code&gt; 的 &lt;code&gt;trait&lt;/code&gt; 时，不能从 &lt;code&gt;&amp;amp;res1.body&lt;/code&gt; 获取长度，以避免内部 &lt;code&gt;body&lt;/code&gt; 成员的所有权转移；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;测试整个相应，自定义响应实例中的请求体数据长度要保持一致；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%B8%89%E3%80%81%E6%9E%84%E5%BB%BAServer%E6%A8%A1%E5%9D%97'&gt;&lt;a name='t8'&gt;&lt;/a&gt;四、构建&lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;Server\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='Server' data-pretit='server'&gt;Server&lt;/span&gt;模块&lt;/h3&gt; 
&lt;hr&gt;
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E6%A8%A1%E5%9D%97%E5%87%86%E5%A4%87'&gt;&lt;a name='t9'&gt;&lt;/a&gt;模块准备&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;此时转至 &lt;code&gt;httpserver&lt;/code&gt; 子项目内，将前文所涉及的 &lt;code&gt;http&lt;/code&gt; 子项目导入 &lt;code&gt;Cargo.toml&lt;/code&gt; 文件；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;并在 &lt;code&gt;httpserver/src&lt;/code&gt; 下再创建三文件&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;server.rs&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;router.rs&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;handler.rs&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='291' src='https://i-blog.csdnimg.cn/blog_migrate/7890dcc60f2c1249410f1770666d6ab8.png' width='505'&gt;&lt;/p&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='249' src='https://i-blog.csdnimg.cn/blog_migrate/d48a0cec6621762c88c7ead4de5bc3e2.png' width='262'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0'&gt;&lt;a name='t10'&gt;&lt;/a&gt;功能实现&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;大概的调用逻辑&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;main - 调用 -&amp;gt; server - 调用 -&amp;gt; router - 调用 -&amp;gt; handler&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;server.rs&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 

```rust
use super::router::Router;
use http::httprequest::HttpRequest;
use std::io::prelude::*;
use std::net::TcpListener;
use std::str;
​
pub struct Server&lt;'a&gt; {
    socket_addr: &amp;'a str,
}
​
impl&lt;'a&gt; Server&lt;'a&gt; {
    pub fn new(socket_addr: &amp;'a str) -&gt; Self {
        Server {socket_addr}
    }
​
    pub fn run(&amp;self) {
        let connection_listener = TcpListener::bind(self.socket_addr).unwrap();
        println!('Running on {}', self.socket_addr);
​
        for stream in connection_listener.incoming() {
            let mut stream = stream.unwrap();
            println!('Connection established');
​
            let mut read_buffer = [0; 200];
            stream.read(&amp;mut read_buffer).unwrap();
​
            let req: HttpRequest = String::from_utf8( read_buffer.to_vec()).unwrap().into();
            Router::route(req, &amp;mut stream);
        }
    }
}
```

&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;实现至当前阶段还不能直接运行；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E5%9B%9B%E3%80%81%E6%9E%84%E5%BB%BA%20Router%20%26%20Handler%20%E6%A8%A1%E5%9D%97'&gt;&lt;a name='t11'&gt;&lt;/a&gt;五、构建 &lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;Router\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='Router' data-pretit='router'&gt;Router&lt;/span&gt; &amp;amp; Handler 模块&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;这两个模块联合起来处理接收到的请求，其中&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;判定请求的合法性，适当返回错误反馈；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;解析后台的数据部分，进行相应的序列化和反序列化；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; &lt;p&gt;不同的请求状况交由不同类型的句柄 &lt;code&gt;Handler&lt;/code&gt; 来处理，同名可重写的方法通过 &lt;code&gt;Trait&lt;/code&gt; 来定义；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;其中的 &lt;strong&gt;handler.rs &lt;/strong&gt;需要引入两个&lt;strong&gt;crate&lt;/strong&gt;&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;strong&gt;serde (&lt;/strong&gt;本文使用的是1.0.140版本&lt;strong&gt;)&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;strong&gt;serde_json (&lt;/strong&gt;本文使用的是1.0.82版本&lt;strong&gt;)&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E5%AE%9E%E7%8E%B0%E4%BB%A3%E7%A0%81'&gt;&lt;a name='t12'&gt;&lt;/a&gt;实现代码&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;router.rs&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 

```rust
use super::handler::{Handler, PageNotFoundHandler, StaticPageHandler, WebServiceHandler};
use http::{httprequest, httprequest::HttpRequest, httpresponse::HttpResponse};
use std::io::prelude::*;
 
pub struct Router;
 
impl Router {
    pub fn route(req: HttpRequest, stream: &amp;mut impl Write) -&gt; () {
        match req.method {
            httprequest::Method::Get =&gt; match &amp;req.resource {
                httprequest::Resource::Path(s) =&gt; {
                    let route: Vec&lt;&amp;str&gt; = s.split('/').collect();
                    match route[1] {
                        'api' =&gt; {
                            let resp: HttpResponse = WebServiceHandler::handle(&amp;req);
                            let _ = resp.send_response(stream);
                        },
                        _ =&gt; {
                            let resp: HttpResponse = StaticPageHandler::handle(&amp;req);
                            let _ = resp.send_response(stream);
                        }
                    }
                }
            },
            _ =&gt; {
                let resp: HttpResponse = PageNotFoundHandler::handle(&amp;req);
                let _ = resp.send_response(stream);
            }
        }
    }
}
```

&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;&lt;code&gt;handler.rs&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 

```rust
use http::{httprequest::HttpRequest, httpresponse::HttpResponse};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::env;
use std::fs;
use std::ops::Index;
​
pub trait Handler {
    fn handle(req: &amp;HttpRequest) -&gt; HttpResponse;
    fn load_file(file_name: &amp;str) -&gt; Option&lt;String&gt; {
        let default_path = format!('{}/public', env!('CARGO_MANIFEST_DIR'));
        let public_path = env::var('PUBLIC_PATH').unwrap_or(default_path);
        let full_path = format!('{}/{}', public_path, file_name);
​
        let contents = fs::read_to_string(full_path);
        contents.ok()
    }
}
​
pub struct StaticPageHandler;
pub struct PageNotFoundHandler;
pub struct WebServiceHandler;
​
#[derive(Serialize, Deserialize)]
pub struct OrderStatus {
    order_id: i32,
    order_date: String,
    order_status: String,
}
​
impl Handler for PageNotFoundHandler {
    fn handle(_req: &amp;HttpRequest) -&gt; HttpResponse {
        HttpResponse::new('404', None, Self::load_file('404.html'))
    }
}
​
impl Handler for StaticPageHandler {
    fn handle(req: &amp;HttpRequest) -&gt; HttpResponse {
        let http::httprequest::Resource::Path(s) = &amp;req.resource;
        let route: Vec&lt;&amp;str&gt; = s.split('/').collect();
        match route[1] {
            '' =&gt; HttpResponse::new('200', None, Self::load_file('index.html')),
            'health' =&gt; HttpResponse::new('200', None, Self::load_file('health.html')),
            path =&gt; match Self::load_file(path) {
                Some(contents) =&gt; {
                    let mut map: HashMap&lt;&amp;str, &amp;str&gt; = HashMap::new();
                    if path.ends_with('.css') {
                        map.insert('Content-Type', 'text/css');
                    } else if path.ends_with('.js') {
                        map.insert('Content-Type', 'text/javascript');
                    } else {
                        map.insert('Content-Type', 'text/html');
                    }
                    HttpResponse::new('200', Some(map), Some(contents))
                },
                None =&gt; HttpResponse::new('404', None, Self::load_file('404.html'))
            }
        }
    }
}
​
impl WebServiceHandler {
    fn load_json() -&gt; Vec&lt;OrderStatus&gt; {
        let default_path = format!('{}/data', env!('CARGO_MANIFEST_DIR'));
        let data_path = env::var('DATA_PATH').unwrap_or(default_path);
        let full_path = format!('{}/{}', data_path, 'orders.json');
        let json_contents = fs::read_to_string(full_path);
        let orders: Vec&lt;OrderStatus&gt; = serde_json::from_str(json_contents.unwrap().as_str()).unwrap();
        orders
    }
}
​
impl Handler for WebServiceHandler {
    fn handle(req: &amp;HttpRequest) -&gt; HttpResponse {
        let http::httprequest::Resource::Path(s) = &amp;req.resource;
        let route: Vec&lt;&amp;str&gt; = s.split('/').collect();
        // localhost:2333/api/air/orders
        match route[2] {
            'air' if route.len() &gt; 2 &amp;&amp; route[3] == 'orders' =&gt; {
                let body = Some(serde_json::to_string(&amp;Self::load_json()).unwrap());
                let mut headers: HashMap&lt;&amp;str, &amp;str&gt; = HashMap::new();
                headers.insert('Content-Type', 'application/json');
                HttpResponse::new('200', Some(headers), body)
            },
            _ =&gt; HttpResponse::new('404', None, Self::load_file('404.html'))
        }
    }
}
```
 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%BA%94%E3%80%81%E5%AE%8C%E6%95%B4%E6%B5%8B%E8%AF%95'&gt;&lt;a name='t13'&gt;&lt;/a&gt;六、完整测试&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在 &lt;code&gt;httpserver&lt;/code&gt; 项目中分别添加&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;data/orders.json&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;public/index.html&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;public/404.html&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;public/health.html&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;&lt;code&gt;styles.css&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;img alt='' height='275' src='https://i-blog.csdnimg.cn/blog_migrate/7cc930412384849c646e5e58043a691c.png' width='316'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;测试文件内容&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 

```html
&lt;!-- index.html --&gt;
​
&lt;!DOCTYPE html&gt;
&lt;html lang='en'&gt;
  &lt;head&gt;
    &lt;meta charset='utf-8' /&gt;
    &lt;link rel='stylesheet' href='styles.css'&gt;
    &lt;title&gt;Index&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Hello,welcome to home page&lt;/h1&gt;
    &lt;p&gt;This is the index page for the web site&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
```

&lt;p&gt;&lt;/p&gt; 

```html
&lt;!-- health.html --&gt;
​
&lt;!DOCTYPE html&gt;
&lt;html lang='en'&gt;
  &lt;head&gt;
    &lt;meta charset='utf-8' /&gt;
    &lt;title&gt;Health!&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Hello,welcome to health page!&lt;/h1&gt;
    &lt;p&gt;This site is perfectly fine&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
```

&lt;p&gt;&lt;/p&gt; 

```html
&lt;!-- 404.html --&gt;
​
&lt;!DOCTYPE html&gt;
&lt;html lang='en'&gt;
&lt;head&gt;
&lt;meta charset='utf-8' /&gt; &lt;title&gt;Not Found!&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;404 Error&lt;/h1&gt;
    &lt;p&gt;Sorry! The requested page does not exist&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
```

&lt;p&gt;&lt;/p&gt; 

```css
/* styles.css */
​
h1 {
     color: red;
     margin-left: 25px;
}
```

&lt;p&gt;&lt;/p&gt; 

```javascript
// orders.json
​
[
  {
    'order_id': 1,
    'order_date': '20 June 2022',
    'order_status': 'Delivered'
  },
  {
    'order_id': 2,
    'order_date': '27 October 2022',
    'order_status': 'Pending'
  }
]
```

&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E8%BF%90%E8%A1%8C'&gt;&lt;a name='t14'&gt;&lt;/a&gt;运行&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;效果如下&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;访问 &lt;code&gt;index.html&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='291' src='https://i-blog.csdnimg.cn/blog_migrate/9886a8eef8a74f79ddc810e4ce017fcd.png' width='785'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;访问 &lt;code&gt;health.html&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='295' src='https://i-blog.csdnimg.cn/blog_migrate/7230d8c795233a8f4ce8507ed3c01cfc.png' width='753'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;访问 &lt;code&gt;orders.json&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='658' src='https://i-blog.csdnimg.cn/blog_migrate/95ccb3947221376a4ba900218aad78c8.png' width='711'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;访问一个错误地址&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='276' src='https://i-blog.csdnimg.cn/blog_migrate/b9ed69d36eda3efb1168ba1a86567549.png' width='522'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;至此，HTTP的基本功能实现就到此为止；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;可以基于此框架做性能优化以及扩展自己所需要的功能；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;通过本次HTTP《简易》设计，可以更深刻地体会一些后端设计思想、Rust本身的特点以及基于HTTP协议的Server设计思路；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p style='text-align:center;'&gt;&lt;strong&gt;每一个不曾起舞的日子，都是对生命的辜负。</description><guid isPermaLink="true">https://AlanKSorata.github.io/post/Rust%20Web%EF%BC%88-er-%EF%BC%89%E2%80%94%E2%80%94%20-zi-jian-HTTP%20Server.html</guid><pubDate>Mon, 30 Mar 2026 03:05:20 +0000</pubDate></item><item><title>Rust Web（一）—— 自建TCP Server</title><link>https://AlanKSorata.github.io/post/Rust%20Web%EF%BC%88-yi-%EF%BC%89%E2%80%94%E2%80%94%20-zi-jian-TCP%20Server.html</link><description>&lt;div id='article_content' class='article_content clearfix'&gt;
        &lt;link rel='stylesheet' href='https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css'&gt;
        &lt;link rel='stylesheet' href='https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-a50b13a894.css'&gt;
                &lt;div id='content_views' class='htmledit_views tomorrow-night'&gt;
                    &lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;前段时间小小学习了一下Rust的基础内容，出于学习Web开发的需求，也为巩固学过的Rust基础，就尝试记录一下自己学习 Rust Web 的点滴；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;实现环境&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;OS: Ubuntu 14.0&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;IDE: PyCharm&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;本文为个人的学习随记，关于Rust的基础部分没有提及太多，难免出现某些细节上的疏漏，还请读者按需参考；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p id='main-toc'&gt;&lt;strong&gt;目录&lt;/strong&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px; padding-left: 24px;'&gt;&lt;a href='#t0' target='_self'&gt;Rust Web（一）—— 自建TCP Server&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 48px; padding-left: 24px;'&gt;&lt;a href='#t1' target='_self'&gt;一、项目创建&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 48px; padding-left: 24px;'&gt;&lt;a href='#t2' target='_self'&gt;二、TCP Server&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t3' target='_self'&gt;库引入&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t4' target='_self'&gt;监听器绑定&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t5' target='_self'&gt;消息接收&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t6' target='_self'&gt;初步运行&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 48px; padding-left: 24px;'&gt;&lt;a href='#t7' target='_self'&gt;三、TCP Client&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t8' target='_self'&gt;库引入&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t9' target='_self'&gt;运行效果&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 48px; padding-left: 24px;'&gt;&lt;a href='#t10' target='_self'&gt;四、消息收发&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t11' target='_self'&gt;Server&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t12' target='_self'&gt;Client&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 96px; padding-left: 24px;'&gt;&lt;a href='#t13' target='_self'&gt;运行效果&lt;/a&gt;&lt;/p&gt; 
&lt;p id='' style='margin: 0px 0px 2px 48px; padding-left: 24px;'&gt;&lt;a href='#t14' target='_self'&gt;五、项目整体结构&lt;/a&gt;&lt;/p&gt; 
&lt;hr id='hr-toc'&gt;
&lt;p&gt;&lt;/p&gt; 
&lt;h2 id='Rust%20Web%EF%BC%88%E4%B8%80%EF%BC%89%E2%80%94%E2%80%94%20%E8%87%AA%E5%BB%BATCP%20Server'&gt;&lt;a name='t0'&gt;&lt;/a&gt;&lt;span class='words-blog hl-git-1' data-tit='Rust' data-pretit='rust'&gt;Rust&lt;/span&gt; &lt;span style='color: #3391E5' class='new-words-blog' data-href='https://ai.csdn.net/?openMirrorId=img697851c35348ba493b73ffb8&amp;amp;utm_source=xtai_slb_kw_0310' data-report-click='{&amp;quot;spm&amp;quot;:&amp;quot;3001.11407&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://ai.csdn.net/?openMirrorId=img697851c35348ba493b73ffb8&amp;amp;utm_source=xtai_slb_kw_0310&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;wordId&amp;quot;:138473,&amp;quot;businessId&amp;quot;:2,&amp;quot;word&amp;quot;:&amp;quot;Web&amp;quot;,&amp;quot;blogTemplateId&amp;quot;:-1}}' data-report-query='spm=1001.2101.3001.11407' data-tit='Web'&gt;
              Web 
              &lt;/span&gt;（一）—— 自建TCP Server&lt;/h2&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%B8%80%E3%80%81%E9%A1%B9%E7%9B%AE%E5%88%9B%E5%BB%BA'&gt;&lt;a name='t1'&gt;&lt;/a&gt;一、&lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;项目\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='项目' data-pretit='项目'&gt;项目&lt;/span&gt;创建&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;在自选的位置使用 &lt;code&gt;cargo&lt;/code&gt; 创建初始项目，此处命名为&lt;code&gt;pro1&lt;/code&gt;；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;&lt;img alt='' height='80' src='https://i-blog.csdnimg.cn/blog_migrate/7886b39b4bc27d29c2508c22d26a61ac.png' width='840'&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;/p&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;进入项目目录，再创建两个子项目，分别为&lt;code&gt;tcpserver&lt;/code&gt;、&lt;code&gt;tcpclient&lt;/code&gt;；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;&lt;img alt='' height='229' src='https://i-blog.csdnimg.cn/blog_migrate/29a8777d9143de556abb8c74c2670f87.png' width='930'&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;/p&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;打开&lt;code&gt;pro1&lt;/code&gt;中的&lt;code&gt;Cargo.toml&lt;/code&gt;文件，将子项目加入当前的工作空间内，具体如下：&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;&lt;img alt='' height='331' src='https://i-blog.csdnimg.cn/blog_migrate/4f26c3d2f9e9cbc9b31f679cc73325ba.png' width='628'&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E4%BA%8C%E3%80%81TCP%20Server'&gt;&lt;a name='t2'&gt;&lt;/a&gt;二、&lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;TCP\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='TCP' data-pretit='tcp'&gt;TCP&lt;/span&gt; Server&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;进入子项目&lt;code&gt;tcpserver&lt;/code&gt;，打开&lt;code&gt;src&lt;/code&gt;下 的&lt;code&gt;main.rs&lt;/code&gt;文件；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;以下是具体的设计过程：&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E5%BA%93%E5%BC%95%E5%85%A5'&gt;&lt;a name='t3'&gt;&lt;/a&gt;库引入&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;引入Rust自带的网络编程库 &lt;code&gt;std::net::TcpListener&lt;/code&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p class='img-center'&gt;&lt;img alt='' height='148' src='https://i-blog.csdnimg.cn/blog_migrate/bb0f29b8af4bb34373908854bdb2be49.png' width='508'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E7%9B%91%E5%90%AC%E5%99%A8%E7%BB%91%E5%AE%9A'&gt;&lt;a name='t4'&gt;&lt;/a&gt;监听器绑定&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;创建一个带有具体&lt;code&gt;IP:port&lt;/code&gt;绑定的监听实例；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;div class='img-center'&gt; 
 &lt;figure class='image'&gt;
  &lt;img alt='' height='148' src='https://i-blog.csdnimg.cn/blog_migrate/78a362e622591fc6d5f6e19f81ffb2c2.png' width='1014'&gt;
  &lt;figcaption&gt;
   绑定监听器
  &lt;/figcaption&gt;
 &lt;/figure&gt;
&lt;/div&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E6%B6%88%E6%81%AF%E6%8E%A5%E6%94%B6'&gt;&lt;a name='t5'&gt;&lt;/a&gt;消息接收&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;p&gt;对于消息的接收，可有两种选择：&lt;/p&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;一种是&lt;strong&gt;只接受一次&lt;/strong&gt;消息后即刻结束运行（实际不常用）；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;另一种是人为中断除外的&lt;strong&gt;无限循环&lt;/strong&gt;接收，而这类方案是实际设计中更为所用的；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;具体实现参考如下&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;一次性接收&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='213' src='https://i-blog.csdnimg.cn/blog_migrate/1f45c469bf5b6f7dd51d2b5cd74e584f.png' width='1006'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;循环接收&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='254' src='https://i-blog.csdnimg.cn/blog_migrate/58bb5959f9fdb40b6b29dca9d4ad35b8.png' width='1067'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;ul&gt;&lt;li&gt; &lt;p&gt;右式中的&lt;code&gt;stream&lt;/code&gt;属于&lt;code&gt;std::result::Result&amp;lt;&amp;gt;&lt;/code&gt;类型，因此需要使用&lt;code&gt;unwrap()&lt;/code&gt;进行简约的异常处理；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;pre data-index='0' class='new-version hljs set-code-height set-code-hide' name='code'&gt;&lt;code class='language-rust hljs'&gt;&lt;ol class='hljs-ln' style='width:100%'&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='1'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;use&lt;/span&gt; std::net::TcpListener;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='2'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='3'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;fn&lt;/span&gt; &lt;span class='hljs-title function_'&gt;main&lt;/span&gt;() {&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='4'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-variable'&gt;listener&lt;/span&gt; = TcpListener::&lt;span class='hljs-title function_ invoke__'&gt;bind&lt;/span&gt;(&lt;span class='hljs-string'&gt;'127.0.0.1:2333'&lt;/span&gt;).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='5'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-built_in'&gt;println!&lt;/span&gt;(&lt;span class='hljs-string'&gt;'Running on port 2333...'&lt;/span&gt;);&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='6'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='7'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;for&lt;/span&gt; &lt;span class='hljs-variable'&gt;stream&lt;/span&gt; &lt;span class='hljs-keyword'&gt;in&lt;/span&gt; listener.&lt;span class='hljs-title function_ invoke__'&gt;incoming&lt;/span&gt;() {&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='8'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-variable'&gt;_stream&lt;/span&gt; = stream.&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='9'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-built_in'&gt;println!&lt;/span&gt;(&lt;span class='hljs-string'&gt;'Connection established!'&lt;/span&gt;);&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='10'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp;  }&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='11'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/code&gt;&lt;div class='opt-box'&gt;&lt;span class='code-language' data-language='rust'&gt;rust&lt;/span&gt;&lt;div class='hljs-button {2}' data-title='复制' onclick='hljs.copyCode(event)'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hide-preCode-box'&gt;&lt;/div&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E5%88%9D%E6%AD%A5%E8%BF%90%E8%A1%8C'&gt;&lt;a name='t6'&gt;&lt;/a&gt;初步运行&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;以下是运行的效果；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
 &lt;p&gt;&lt;img alt='' height='162' src='https://i-blog.csdnimg.cn/blog_migrate/2801da4cd837580b875a0ea217853746.png' width='812'&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='TCP%20Client'&gt;&lt;a name='t7'&gt;&lt;/a&gt;三、TCP &lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;Client\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='Client' data-pretit='client'&gt;Client&lt;/span&gt;&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;进入子项目&lt;strong&gt;&lt;code&gt;tcpclient&lt;/code&gt;&lt;/strong&gt;，转到&amp;nbsp;&lt;strong&gt;&lt;code&gt;src/main.rs&lt;/code&gt;&lt;/strong&gt;；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;具体步骤如下：&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4&gt;&lt;a name='t8'&gt;&lt;/a&gt;库引入&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;引入Rust自带库 &lt;strong&gt;&lt;code&gt;std::net::TcpStream&lt;/code&gt;&lt;/strong&gt;；&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;创建一个数据流实例来连接指定地址的服务端；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;pre data-index='1' class='new-version hljs set-code-show' name='code'&gt;&lt;code class='language-rust hljs'&gt;&lt;ol class='hljs-ln' style='width:100%'&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='1'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;use&lt;/span&gt; std::net::TcpStream;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='2'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='3'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;fn&lt;/span&gt; &lt;span class='hljs-title function_'&gt;main&lt;/span&gt;() {&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='4'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-variable'&gt;stream&lt;/span&gt; = TcpStream::&lt;span class='hljs-title function_ invoke__'&gt;connect&lt;/span&gt;(&lt;span class='hljs-string'&gt;'127.0.0.1:2333'&lt;/span&gt;).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='5'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/code&gt;&lt;div class='opt-box'&gt;&lt;button class='btn-code-notes ckeditor' style='background-image:url(https://i-operation.csdnimg.cn/images/a5fff6f6c9f0464c9a46b130c972952b.png);' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10436&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://trae.com.cn?utm_source=community&amp;amp;utm_medium=csdn&amp;amp;utm_campaign=daima&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;index&amp;quot;:1,&amp;quot;ab&amp;quot;:&amp;quot;control&amp;quot;}}' data-report-click='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10436&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://trae.com.cn?utm_source=community&amp;amp;utm_medium=csdn&amp;amp;utm_campaign=daima&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;index&amp;quot;:1,&amp;quot;ab&amp;quot;:&amp;quot;control&amp;quot;}}'&gt;AI写代码&lt;/button&gt;&lt;span class='code-language' data-language='rust'&gt;rust&lt;/span&gt;&lt;div class='hljs-button {2}' data-title='复制' onclick='hljs.copyCode(event)'&gt;&lt;/div&gt;&lt;span class='code-run-btn' data-idx='1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10758&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;language&amp;quot;:&amp;quot;rust&amp;quot;, &amp;quot;idx&amp;quot;:&amp;quot;1&amp;quot;}}' data-language='rust'&gt;运行&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E8%BF%90%E8%A1%8C%E6%95%88%E6%9E%9C'&gt;&lt;a name='t9'&gt;&lt;/a&gt;运行效果&lt;/h4&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Client&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='198' src='https://i-blog.csdnimg.cn/blog_migrate/f18044548272b8656e02a7d5827d3a50.png' width='807'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='214' src='https://i-blog.csdnimg.cn/blog_migrate/2fd642d157eb89b5a4a52ffebebd20bd.png' width='795'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E6%B6%88%E6%81%AF%E6%94%B6%E5%8F%91'&gt;&lt;a name='t10'&gt;&lt;/a&gt;四、消息收发&lt;/h3&gt; 
&lt;hr&gt;
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;由于所引入的网络编程库中实现了&lt;strong&gt;读写的 Trait&lt;/strong&gt;，因此需要引入两个 &lt;strong&gt;Trait&lt;/strong&gt;&lt;/p&gt; 
   &lt;ul&gt;&lt;li&gt; &lt;p&gt;&lt;strong&gt;&lt;code&gt;std::io::{Read, Write}&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; &lt;p&gt;TCP消息传送中的读写使用&lt;strong&gt;原始字节串&lt;/strong&gt;形式；&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E6%9C%8D%E5%8A%A1%E7%AB%AF'&gt;&lt;a name='t11'&gt;&lt;/a&gt;&lt;span class='words-blog hl-git-1' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.10283&amp;quot;,&amp;quot;extra&amp;quot;:&amp;quot;{\&amp;quot;words\&amp;quot;:\&amp;quot;Server\&amp;quot;,\&amp;quot;isNewGitCodeAB\&amp;quot;:1}&amp;quot;}' data-tit='Server' data-pretit='server'&gt;Server&lt;/span&gt;&lt;/h4&gt; 
&lt;pre data-index='2' class='new-version hljs set-code-height set-code-hide' name='code'&gt;&lt;code class='language-rust hljs'&gt;&lt;ol class='hljs-ln' style='width:100%'&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='1'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;use&lt;/span&gt; std::net::TcpListener;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='2'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;use&lt;/span&gt; std::io::{Read, Write};&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='3'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='4'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;fn&lt;/span&gt; &lt;span class='hljs-title function_'&gt;main&lt;/span&gt;() {&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='5'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-variable'&gt;listener&lt;/span&gt; = TcpListener::&lt;span class='hljs-title function_ invoke__'&gt;bind&lt;/span&gt;(&lt;span class='hljs-string'&gt;'127.0.0.1:2333'&lt;/span&gt;).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='6'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-built_in'&gt;println!&lt;/span&gt;(&lt;span class='hljs-string'&gt;'Running on port 2333...'&lt;/span&gt;);&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='7'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='8'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;for&lt;/span&gt; &lt;span class='hljs-variable'&gt;stream&lt;/span&gt; &lt;span class='hljs-keyword'&gt;in&lt;/span&gt; listener.&lt;span class='hljs-title function_ invoke__'&gt;incoming&lt;/span&gt;() {&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='9'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-keyword'&gt;mut &lt;/span&gt;&lt;span class='hljs-variable'&gt;stream&lt;/span&gt; = stream.&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='10'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-built_in'&gt;println!&lt;/span&gt;(&lt;span class='hljs-string'&gt;'Connection established!'&lt;/span&gt;);&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='11'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='12'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-keyword'&gt;mut &lt;/span&gt;&lt;span class='hljs-variable'&gt;buffer&lt;/span&gt; = [&lt;span class='hljs-number'&gt;0&lt;/span&gt;; &lt;span class='hljs-number'&gt;1024&lt;/span&gt;];&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='13'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;stream.&lt;span class='hljs-title function_ invoke__'&gt;read&lt;/span&gt;(&amp;amp;&lt;span class='hljs-keyword'&gt;mut&lt;/span&gt; buffer).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='14'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;stream.&lt;span class='hljs-title function_ invoke__'&gt;write&lt;/span&gt;(&amp;amp;&lt;span class='hljs-keyword'&gt;mut&lt;/span&gt; buffer).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='15'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp;  }&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='16'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/code&gt;&lt;div class='opt-box'&gt;&lt;button class='btn-code-notes ckeditor' style='background-image:url(https://i-operation.csdnimg.cn/images/a5fff6f6c9f0464c9a46b130c972952b.png);' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10436&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://trae.com.cn?utm_source=community&amp;amp;utm_medium=csdn&amp;amp;utm_campaign=daima&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;index&amp;quot;:2,&amp;quot;ab&amp;quot;:&amp;quot;control&amp;quot;}}' data-report-click='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10436&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://trae.com.cn?utm_source=community&amp;amp;utm_medium=csdn&amp;amp;utm_campaign=daima&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;index&amp;quot;:2,&amp;quot;ab&amp;quot;:&amp;quot;control&amp;quot;}}'&gt;AI写代码&lt;/button&gt;&lt;span class='code-language' data-language='rust'&gt;rust&lt;/span&gt;&lt;div class='hljs-button {2}' data-title='复制' onclick='hljs.copyCode(event)'&gt;&lt;/div&gt;&lt;span class='code-run-btn' data-idx='2' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10758&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;language&amp;quot;:&amp;quot;rust&amp;quot;, &amp;quot;idx&amp;quot;:&amp;quot;2&amp;quot;}}' data-language='rust'&gt;运行&lt;/span&gt;&lt;/div&gt;&lt;div class='hide-preCode-box'&gt;&lt;span class='hide-preCode-bt' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.7365&amp;quot;}'&gt;&lt;img class='look-more-preCode contentImg-no-view' src='https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowblack.png' alt='' title=''&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4 id='%E5%AE%A2%E6%88%B7%E7%AB%AF'&gt;&lt;a name='t12'&gt;&lt;/a&gt;Client&lt;/h4&gt; 
&lt;blockquote&gt; 
 &lt;ul&gt;&lt;li&gt; &lt;p&gt;客户端处需要额外进入库 &lt;strong&gt;&lt;code&gt;std::str&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;pre data-index='3' class='new-version hljs set-code-height set-code-hide' name='code'&gt;&lt;code class='language-rust hljs'&gt;&lt;ol class='hljs-ln' style='width:100%'&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='1'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;use&lt;/span&gt; std::net::TcpStream;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='2'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;use&lt;/span&gt; std::io::{Read, Write};&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='3'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;use&lt;/span&gt; std::&lt;span class='hljs-type'&gt;str&lt;/span&gt;;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='4'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='5'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;&lt;span class='hljs-keyword'&gt;fn&lt;/span&gt; &lt;span class='hljs-title function_'&gt;main&lt;/span&gt;() {&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='6'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-keyword'&gt;mut &lt;/span&gt;&lt;span class='hljs-variable'&gt;stream&lt;/span&gt; = TcpStream::&lt;span class='hljs-title function_ invoke__'&gt;connect&lt;/span&gt;(&lt;span class='hljs-string'&gt;'127.0.0.1:2333'&lt;/span&gt;).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='7'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;stream.&lt;span class='hljs-title function_ invoke__'&gt;write&lt;/span&gt;(&lt;span class='hljs-string'&gt;'Here's CLient End'&lt;/span&gt;.&lt;span class='hljs-title function_ invoke__'&gt;as_bytes&lt;/span&gt;()).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='8'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='9'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-keyword'&gt;let&lt;/span&gt; &lt;span class='hljs-keyword'&gt;mut &lt;/span&gt;&lt;span class='hljs-variable'&gt;buffer&lt;/span&gt; = [&lt;span class='hljs-number'&gt;0&lt;/span&gt;; &lt;span class='hljs-number'&gt;17&lt;/span&gt;]; &lt;span class='hljs-comment'&gt;// 此处的 17 是为配合消息的长度&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='10'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;stream.&lt;span class='hljs-title function_ invoke__'&gt;read&lt;/span&gt;(&amp;amp;&lt;span class='hljs-keyword'&gt;mut&lt;/span&gt; buffer).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;();&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='11'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;​&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='12'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp;&lt;span class='hljs-built_in'&gt;println!&lt;/span&gt;(&lt;span class='hljs-string'&gt;'Response from server: {:?}'&lt;/span&gt;,&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='13'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class='hljs-type'&gt;str&lt;/span&gt;::&lt;span class='hljs-title function_ invoke__'&gt;from_utf8&lt;/span&gt;(&amp;amp;&lt;span class='hljs-keyword'&gt;mut&lt;/span&gt; buffer).&lt;span class='hljs-title function_ invoke__'&gt;unwrap&lt;/span&gt;() &lt;span class='hljs-comment'&gt;// utf-8编码形式接收&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='14'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt; &amp;nbsp;  );&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div class='hljs-ln-numbers'&gt;&lt;div class='hljs-ln-line hljs-ln-n' data-line-number='15'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class='hljs-ln-code'&gt;&lt;div class='hljs-ln-line'&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/code&gt;&lt;div class='opt-box'&gt;&lt;button class='btn-code-notes ckeditor' style='background-image:url(https://i-operation.csdnimg.cn/images/a5fff6f6c9f0464c9a46b130c972952b.png);' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10436&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://trae.com.cn?utm_source=community&amp;amp;utm_medium=csdn&amp;amp;utm_campaign=daima&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;index&amp;quot;:3,&amp;quot;ab&amp;quot;:&amp;quot;control&amp;quot;}}' data-report-click='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10436&amp;quot;,&amp;quot;dest&amp;quot;:&amp;quot;https://trae.com.cn?utm_source=community&amp;amp;utm_medium=csdn&amp;amp;utm_campaign=daima&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;index&amp;quot;:3,&amp;quot;ab&amp;quot;:&amp;quot;control&amp;quot;}}'&gt;AI写代码&lt;/button&gt;&lt;span class='code-language' data-language='rust'&gt;rust&lt;/span&gt;&lt;div class='hljs-button {2}' data-title='复制' onclick='hljs.copyCode(event)'&gt;&lt;/div&gt;&lt;span class='code-run-btn' data-idx='3' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;3001.10758&amp;quot;,&amp;quot;extra&amp;quot;:{&amp;quot;language&amp;quot;:&amp;quot;rust&amp;quot;, &amp;quot;idx&amp;quot;:&amp;quot;3&amp;quot;}}' data-language='rust'&gt;运行&lt;/span&gt;&lt;/div&gt;&lt;div class='hide-preCode-box'&gt;&lt;span class='hide-preCode-bt' data-report-view='{&amp;quot;spm&amp;quot;:&amp;quot;1001.2101.3001.7365&amp;quot;}'&gt;&lt;img class='look-more-preCode contentImg-no-view' src='https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowblack.png' alt='' title=''&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h4&gt;&lt;a name='t13'&gt;&lt;/a&gt;运行效果&lt;/h4&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='208' src='https://i-blog.csdnimg.cn/blog_migrate/b9d3dc6202df95510cd0fc9d35a7beeb.png' width='821'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Client&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;&lt;img alt='' height='202' src='https://i-blog.csdnimg.cn/blog_migrate/ffacae8625935b23e50f37fa188ef595.png' width='780'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;h3 id='%E9%A1%B9%E7%9B%AE%E6%95%B4%E4%BD%93%E7%BB%93%E6%9E%84'&gt;&lt;a name='t14'&gt;&lt;/a&gt;五、项目整体结构&lt;/h3&gt; 
&lt;hr&gt;
&lt;p class='img-center'&gt;&lt;img alt='' height='410' src='https://i-blog.csdnimg.cn/blog_migrate/d74ade0b029a5482079b351d12dc599b.png' width='373'&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;p&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
 &lt;p style='text-align:center;'&gt;&lt;strong&gt;每一个不曾起舞的日子，都是对生命的辜负。</description><guid isPermaLink="true">https://AlanKSorata.github.io/post/Rust%20Web%EF%BC%88-yi-%EF%BC%89%E2%80%94%E2%80%94%20-zi-jian-TCP%20Server.html</guid><pubDate>Mon, 30 Mar 2026 02:48:14 +0000</pubDate></item></channel></rss>