20210310 troubleshoot wi fi problems with go and a raspberry pi (#25525)

* Update 20210310 Troubleshoot WiFi problems with Go and a Raspberry Pi.md

* Update 20210310 Troubleshoot WiFi problems with Go and a Raspberry Pi.md

* Update 20210310 Troubleshoot WiFi problems with Go and a Raspberry Pi.md

* Update 20210310 Troubleshoot WiFi problems with Go and a Raspberry Pi.md

* Update 20210310 Troubleshoot WiFi problems with Go and a Raspberry Pi.md
This commit is contained in:
SamMa
2022-05-07 10:15:39 +08:00
committed by GitHub
parent deabb17741
commit 2b8dca2390

View File

@@ -3,32 +3,32 @@
[#]: author: "Chris Collins https://opensource.com/users/clcollins"
[#]: collector: "lkxed"
[#]: translator: "lkxed"
[#]: reviewer: " "
[#]: reviewer: "turbokernel"
[#]: publisher: " "
[#]: url: " "
使用 Go 和树莓派来解决 WiFi 问题
使用 Go 和树莓派排查 WiFi 问题
======
实现一个 WiFi 扫描玩玩~
实现一个 WiFi 扫描玩玩~
![在在门廊上喝茶][1]
图源opensource.com
去年夏天,我和妻子卖掉了我们的全部财产,带着我们的两只狗搬到了夏威夷。这里有我们想象中的一切:美丽的阳光、温暖的沙滩、凉爽的冲浪 —— 你能想到的一切。我们遇到了一些意料之外的事WiFi 问题。
去年夏天,我和妻子变卖了家产,带着我们的两只狗移居了夏威夷。这里有美丽的阳光、温暖的沙滩、凉爽的冲浪你能想到的一切。我们同样遇到了一些意料之外的事WiFi 问题。
不过,这不是夏威夷的问题,而是我们租住公寓的问题。我们住在一个单身公寓里,与房东的公寓仅一墙之隔。我们的租房协议中包含了免费的网络连接!好耶!只不过,它是由房东的公寓里的 WiFi 提供的,哇哦……
不过,这不是夏威夷的问题,而是我们租住公寓的问题。我们住在一个单身公寓里,与房东的公寓仅一墙之隔。我们的租房协议中包含了免费的网络连接!好耶!只不过,它是由房东的公寓里的 WiFi 提供的,哇哦……
说实话,它的效果还不错……吗?好吧,我承认它不尽如人意,我也不知道是哪里出了问题。明明路由器就在墙的另一边,但我们的信号就是很不稳定,经常会自动断开连接。在家的时候,我们的 WiFi 路由器的信号能够穿过层层墙壁和地板。事实上,它所覆盖的区域比我们居住的 600 平方英尺(大约 55 平方米)的公寓还要大。
说实话,它的效果还不错……吗?好吧,我承认它不尽如人意,并且不知道是哪里问题。路由器明明就在墙的另一边,但我们的信号就是很不稳定,经常会自动断开连接。在家的时候,我们的 WiFi 路由器的信号能够穿过层层墙壁和地板。事实上,它所覆盖的区域比我们居住的 600 平方英尺(大约 55 平方米)的公寓还要大。
在这种情况下,一个优秀的技术人员会怎么做呢?既然想知道为什么,当然是开始查咯!
在这种情况下,一个优秀的技术人员会怎么做呢?既然想知道为什么,当然是开始查咯!
幸运的是,我们在搬家之前卖掉的“全部财产”并不包括树莓派 Zero W。它是如此小! 如此便携! 我当然就把它一起带来了。我有一个机智的想法:使用树莓派和它内置的 WiFi 适配器,用 Go 语言编写一个小程序来测量并显示从路由器收到的 WiFi 信号。我打算先简单快速地把它实现出来,以后再去考虑该如何优化。烦死了!我现在只想知道这个 WiFi 是怎么回事!
幸运的是,我们在搬家之前并没有变卖掉树莓派 Zero W。它是如此小便携! 我当然就把它一起带来了。我有一个机智的想法:通过树莓派和它内置的 WiFi 适配器,使用 Go 语言编写一个小程序来测量并显示从路由器收到的 WiFi 信号。我打算先简单快速地把它实现出来,以后再去考虑优化。烦死了!我现在只想知道这个 WiFi 是怎么回事!
谷歌搜索了一番后,我发现了一个相对有用的 Go 软件包 [mdlayher/wifi][2],它专门用于 WiFi 相关操作,听起来很有希望!
谷歌搜索了一番后,我发现了一个相对有用的 Go 依赖包 [mdlayher/wifi][2],它专门用于 WiFi 相关操作,听起来很有希望!
### 获取 WiFi 接口的信息
计划是查询 WiFi 接口的统计数据并返回信号强度所以我需要先找到设备上的接口。幸运的是mdlayher/wifi 包有一个查询它们的方法,所以我可以创建一个 `main.go` 来实现它,就像下面这样
我计划遍历 WiFi 接口的统计数据并返回信号强度所以我需要先找到设备上的接口。幸运的是mdlayher/wifi 包有一个查询它们的方法,所以我可以创建一个 `main.go` 来实现它,具体代码如下
```go
package main
@@ -54,9 +54,9 @@ func main() {
}
```
让我们来看看上面的代码都做了什么吧!嗯,首先是导入依赖模块,导入后,我就可以使用 mdlayher/wifi 模块就在函数中创建一个新的客户端(类型为 `*Client`)。接下来,这个新的客户端(变量名为 `c`就可以获得系统中的接口列表,只需要调用 `c.Interfaces()` 方法即可。接着,我就可以遍历包含接口指针的切片(变长数组),然后打印出它们的具体信息。
让我们来看看上面的代码都做了什么吧!首先是导入依赖,导入后,我就可以使用 mdlayher/wifi 模块就在 main 函数中创建一个新的客户端(类型为 `*Client`)。接下来,只需要调用这个新的客户端(变量名为 `c` `c.Interfaces()` 方法就可以获得系统中的接口列表。接着,我就可以遍历包含接口指针的切片(变长数组),然后打印出它们的具体信息。
注意到 `%+v` 中有一个 “+” 了吗?它意味着程序会额外打印`*Interface` 结构中的属性名,这将有助于我辨认出我看到的东西,而不用回头去看文档。
注意到 `%+v` 中有一个 “+” 了吗?它意味着程序会详细输`*Interface` 结构中的属性名,这将有助于我标识出我看到的东西,而不用去查阅文档。
运行上面的代码后,我得到了机器上的 WiFi 接口列表:
@@ -65,15 +65,15 @@ func main() {
&{Index:3 Name:wlp2s0 HardwareAddr:5c:5f:67:f3:0a:a7 PHY:0 Device:1 Type:station Frequency:2412}
```
注意,两行输出中的 MAC 地址都是 `HardwareAddr`,这意味着它们是同一个物理硬件。你也可以通过 `PHY: 0` 来确认。根据 Go 的 [wifi 模块文档][3]`PHY` 指的就是接口所属的物理设备。
注意,两行输出中的 MAC 地址(`HardwareAddr`) 是相同的,这意味着它们是同一个物理硬件。你也可以通过 `PHY: 0` 来确认。查阅 Go 的 [wifi 模块文档][3]`PHY` 指的就是接口所属的物理设备。
第一个接口没有名字,类型是 `TYPE: P2P`。第二个接口名为 `wpl2s0`,类型是 `TYPE: Station`。Go 的 wifi 模块文档列出了 [不同类型的接口][4]并描述了它们是什么。根据文档,“<ruby>P2P<rt>点对点传输</rt></ruby>” 类型表示“这个接口是点对点客户端网络中的一个设备”。我认为这个接口是用于 [WiFi 直连][5] ,这是一个允许两个 WiFi 设备在没有中间接入点的情况下直接连接的标准。
第一个接口没有名字,类型是 `TYPE: P2P`。第二个接口名为 `wpl2s0`,类型是 `TYPE: Station`。Go 的 wifi 模块文档列出了 [不同类型的接口][4]以及他们的用途。根据文档,“<ruby>P2P<rt>点对点传输</rt></ruby>” 类型表示“该接口属于点对点客户端网络中的一个设备”。我认为这个接口的用途是 [WiFi 直连][5] ,这是一个允许两个 WiFi 设备在没有中间接入点的情况下直接连接的标准。
“<ruby>Station<rt>基站</rt></ruby>” 类型表示“这个接口是有<ruby>控制接入点<rt>controlling access point</rt></ruby>的客户端设备管理的<ruby>基本服务集BSS<rt>basic service set</rt></ruby>的一部分”。这是大多数人所习惯的无线设备标准功能,也就是作为一个客户端来连接到网络接入点。这是测试 WiFi 质量的重要接口。
“<ruby>Station<rt>基站</rt></ruby>” 类型表示“接口是有<ruby>控制接入点<rt>controlling access point</rt></ruby>的客户端设备管理的<ruby>基本服务集BSS<rt>basic service set</rt></ruby>的一部分”。这是大众熟悉的无线设备标准功能,也作为一个客户端来连接到网络接入点。这是测试 WiFi 质量的重要接口。
### 利用接口获取基站信息
利用这个信息,我可以修改遍历接口的代码来获取我正在寻找的信息:
利用信息,我可以修改遍历接口的代码来获取所需信息:
```go
for _, x := range interfaces {
@@ -91,7 +91,7 @@ for _, x := range interfaces {
}
```
首先,这段程序检查了 `x.Type`(接口类型)是否为 `wifi.InterfaceTypeStation`,它是一个基站接口(也是本练习中唯一涉及到的类型)。这是一个不幸的命名冲突,因为这个接口“类型”和 Golang 中的“类型”不是一个东西。事实上,我在这里使用了一个叫做 `interfaceType` 的 Go 类型来代表接口类型。呼,我花了一分钟才弄明白!
首先,这段程序检查了 `x.Type`(接口类型)是否为 `wifi.InterfaceTypeStation`,它是一个基站接口(也是本练习中唯一涉及到的类型)。不幸的是,这个接口“类型”和 Golang 中的“类型”存在命名冲突。事实上,我在这里使用了一个叫做 `interfaceType` 的 Go 类型来代表接口类型。呼,我花了一分钟才弄明白!
然后,假设接口的类型符合预期,我们就可以调用 `c.StationInfo(x)` 来检索基站信息,`StationInfo()` 方法可以获取到关于这个接口 `x` 的信息。
@@ -117,9 +117,9 @@ for _, x := range interfaces {
*注意dBm 是对数尺度,-60 比 -30 要低 1000 倍。*
### 使它成为一个真的“扫描
### 使它成为一个真的“扫描
所以,看着上面输出显示的我的信号:-79。哇哦感觉不大好呢。不过单看这个结果并没有太大帮助它只能提供某个时间点的参考只对 WiFi 网络适配器在那一瞬间所在的特定物理空间有效。一个连续的读数会更有用,它能使我们有可能看到信号随着树莓派的移动而变化。我可以再次修改主函数来实现这一点。
所以,看着上面输出显示的我的信号:-79。哇哦感觉不大好呢。不过单看这个结果并没有太大帮助它只能提供某个时间点的参考只对 WiFi 网络适配器在特定物理空间的某一瞬间有效。一个连续的读数会更有用,借助于它,我们观察到信号随着树莓派的移动而变化。我可以再次修改主函数来实现这一点。
```go
var i *wifi.Interface
@@ -155,7 +155,7 @@ for {
然后,我可以把这个循环一分为二。第一个遍历了 `c.Interfaces()` 返回的接口切片,如果元素是一个 `Station` 类型,它就将其存储在先前创建的变量 `i`中,并跳出循环。
第二个循环是一个无限循环,所以它将不断地运行,直到我按下 **Ctrl** + **C** 来结束程序。和之前一样,这个循环内部获取接口信息、检索基站信息,并打印出信号信息。然后它会休眠一秒钟,再次运行,反复打印信号信息,直到我退出为止。
第二个循环是一个循环,它将不断地运行,直到我按下 **Ctrl** + **C** 来结束程序。和之前一样,这个循环内部获取接口信息、检索基站信息,并打印出信号信息。然后它会休眠一秒钟,再次运行,反复打印信号信息,直到我退出为止。
运行上面的程序后,我得到了下面的输出:
@@ -188,7 +188,7 @@ via: https://opensource.com/article/21/3/troubleshoot-wifi-go-raspberry-pi
作者:[Chris Collins][a]
选题:[lkxed][b]
译者:[lkxed](https://github.com/lkxed)
校对:[校对者ID](https://github.com/校对者ID)
校对:[turbokernel](https://github.com/turbokernel)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出