赞
踩
所以我们的 web server 所需做的第一件事便是能够监听 TCP 连接。标准库提供了 std:: net 模块处理这
些功能。让我们一如既往新建一个项目:
$ cargo new hello
Created binary (application) hello
project
$ cd hello
并在 src∕main.rs 输入示例 20-1 中的代码作为开始。这段代码会在地址 127.0.0.1:7878 上监听传入的
TCP 流。当获取到传入的流,它会打印出 Connection established!:
文件名: src∕main.rs
use std::net::TcpListener;
fn main() {
let listener = TcpListener::bind(“127.0.0.1:7878”).unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
println!(“Connection established!”);
}
}
示例 20-1: 监听传入的流并在接收到流时打印信息
TcpListener 用于监听 TCP 连接。我们选择监听地址 127.0.0.1:7878。将这个地址拆开,冒号之前的部
分是一个代表本机的 IP 地址(这个地址在每台计算机上都相同,并不特指作者的计算机),而 7878 是
端口。选择这个端口出于两个原因:通常 HTTP 接受这个端口而且 7878 在电话上打出来就是 ”rust”(译
者注:九宫格键盘上的英文)。
在这个场景中 bind 函数类似于 new 函数,在这里它返回一个新的 TcpListener 实例。这个函数叫做
bind 是因为,在网络领域,连接到监听端口被称为 ” 绑定到一个端口”(”binding to a port”)
bind 函数返回 Result<T, E>,这表明绑定可能会失败,例如,连接 80 端口需要管理员权限(非管理员
用户只能监听大于 1024 的端口),所以如果不是管理员尝试连接 80 端口,则会绑定失败。另一个例子
526 CHAPTER 20. 最后的项目: 构建多线程 WEB SERVER
是如果运行两个此程序的实例这样会有两个程序监听相同的端口,绑定会失败。因为我们是出于学习目
的来编写一个基础的 server,将不用关心处理这类错误,使用 unwrap 在出现这些情况时直接停止程序。
TcpListener 的 incoming 方法返回一个迭代器,它提供了一系列的流(更准确的说是 TcpStream 类型
的流)。流(stream)代表一个客户端和服务端之间打开的连接。连接(connection)代表客户端连接服
务端、服务端生成响应以及服务端关闭连接的全部请求 ∕ 响应过程。为此,TcpStream 允许我们读取它
来查看客户端发送了什么,并可以编写响应。总体来说,这个 for 循环会依次处理每个连接并产生一系
列的流供我们处理。
目前为止,处理流的过程包含 unwrap 调用,如果出现任何错误会终止程序,如果没有任何错误,则打
印出信息。下一个示例我们将为成功的情况增加更多功能。当客户端连接到服务端时 incoming 方法返
回错误是可能的,因为我们实际上没有遍历连接,而是遍历 连接尝试(connection attempts)。连接可
能会因为很多原因不能成功,大部分是操作系统相关的。例如,很多系统限制同时打开的连接数;新连
接尝试产生错误,直到一些打开的连接关闭为止。
让我们试试这段代码!首先在终端执行 cargo run,接着在浏览器中加载 127.0.0.1:7878。浏览器会显
示出看起来类似于” 连接重置”(”Connection reset”)的错误信息,因为 server 目前并没响应任何数据。
但是如果我们观察终端,会发现当浏览器连接 server 时会打印出一系列的信息!
Running target/debug/hello
Connection established!
Connection established!
Connection established!
有时会看到对于一次浏览器请求会打印出多条信息;这可能是因为浏览器在请求页面的同时还请求了其
他资源,比如出现在浏览器 tab 标签中的 favicon.ico。
这也可能是因为浏览器尝试多次连接 server,因为 server 没有响应任何数据。当 stream 在循环的结尾
离开作用域并被丢弃,其连接将被关闭,作为 drop 实现的一部分。浏览器有时通过重连来处理关闭的
连接,因为这些问题可能是暂时的。现在重要的是我们成功的处理了 TCP 连接!
记得当运行完特定版本的代码后使用 ctrl-C 来停止程序。并在做出最新的代码修改之后执行 cargo run
重启服务。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。