0
点赞
收藏
分享

微信扫一扫

rust 监听 TCP 连接

所以我们的 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

重启服务。

举报

相关推荐

0 条评论