成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用 Go 和樹莓派排查 WiFi 問題

開發 后端
實現一個 WiFi 掃描器玩玩~

去年夏天,我和妻子變賣了家產,帶著我們的兩只狗移居了夏威夷。這里有美麗的陽光、溫暖的沙灘、涼爽的沖浪等你能想到的一切。我們同樣遇到了一些意料之外的事:WiFi 問題。

不過,這不是夏威夷的問題,而是我們租住公寓的問題。我們住在一個單身公寓里,與房東的公寓僅一墻之隔。我們的租房協議中包含了免費的網絡連接!好耶!只不過,它是由房東的公寓里的 WiFi 提供的,哇哦……

說實話,它的效果還不錯……吧?好吧,我承認它不盡如人意,并且不知道是哪里的問題。路由器明明就在墻的另一邊,但我們的信號就是很不穩定,經常會自動斷開連接。在家的時候,我們的 WiFi 路由器的信號能夠穿過層層墻壁和地板。事實上,它所覆蓋的區域比我們居住的 600 平方英尺(大約 55 平方米)的公寓還要大。

在這種情況下,一個優秀的技術人員會怎么做呢?既然想知道為什么,當然是開始排查咯!

幸運的是,我們在搬家之前并沒有變賣掉樹莓派 Zero W。它是如此小巧便攜! 我當然就把它一起帶來了。我有一個機智的想法:通過樹莓派和它內置的 WiFi 適配器,使用 Go 語言編寫一個小程序來測量并顯示從路由器收到的 WiFi 信號。我打算先簡單快速地把它實現出來,以后再去考慮優化。真是麻煩!我現在只想知道這個 WiFi 是怎么回事!

谷歌搜索了一番后,我發現了一個比較有用的 Go 軟件包 ??mdlayher/wifi??,它專門用于 WiFi 相關操作,聽起來很有希望!

獲取 WiFi 接口的信息

我的計劃是查詢 WiFi 接口的統計數據并返回信號強度,所以我需要先找到設備上的接口。幸運的是,??mdlayher/wifi??? 包有一個查詢它們的方法,所以我可以創建一個 ??main.go?? 來實現它,具體代碼如下:

package main

import (
"fmt"
"github.com/mdlayher/wifi"
)

func main() {
c, err := wifi.New()
defer c.Close()

if err != nil {
panic(err)
}

interfaces, err := c.Interfaces()

for _, x := range interfaces {
fmt.Printf("%+v\n", x)
}
}

讓我們來看看上面的代碼都做了什么吧!首先是導入依賴包,導入后,我就可以使用 ??mdlayher/wifi??? 模塊就在 ??main??? 函數中創建一個新的客戶端(類型為 ??*Client???)。接下來,只需要調用這個新的客戶端(變量名為 ??c???)的 ??c.Interfaces()?? 方法就可以獲得系統中的接口列表。接著,我就可以遍歷包含接口指針的切片(變長數組),然后打印出它們的具體信息。

注意到 ??%+v??? 中有一個 ??+??? 了嗎?它意味著程序會詳細輸出 ??*Interface?? 結構體中的屬性名,這將有助于我標識出我看到的東西,而不用去查閱文檔。

運行上面的代碼后,我得到了機器上的 WiFi 接口列表:

&{Index:0 Name: HardwareAddr:5c:5f:67:f3:0a:a7 PHY:0 Device:3 Type:P2P device Frequency:0}
&{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 模塊文檔???,??PHY?? 指的就是接口所屬的物理設備。

第一個接口沒有名字,類型是 ??TYPE: P2P???。第二個接口名為 ??wpl2s0???,類型是 ??TYPE: Station???。??wifi??? 模塊的文檔列出了 ??不同類型的接口???,以及它們的用途。根據文檔,??P2P???(點對點傳輸) 類型表示“該接口屬于點對點客戶端網絡中的一個設備”。我認為這個接口的用途是 ??WiFi 直連?? ,這是一個允許兩個 WiFi 設備在沒有中間接入點的情況下直接連接的標準。

??Station??(基站)類型表示“該接口是具有控制接入點controlling access point的客戶端設備管理的基本服務集basic service set(BSS)的一部分”。這是大眾熟悉的無線設備標準功能:作為一個客戶端來連接到網絡接入點。這是測試 WiFi 質量的重要接口。

利用接口獲取基站信息

利用該信息,我可以修改遍歷接口的代碼來獲取所需信息:

for _, x := range interfaces {
if x.Type == wifi.InterfaceTypeStation {
// c.StationInfo(x) returns a slice of all
// the staton information about the interface
info, err := c.StationInfo(x)
if err != nil {
fmt.Printf("Station err: %s\n", err)
}
for _, x := range info {
fmt.Printf("%+v\n", x)
}
}
}

首先,這段程序檢查了 ??x.Type???(接口類型)是否為 ??wifi.InterfaceTypeStation???,它是一個基站接口(也是本練習中唯一涉及到的類型)。不幸的是名字出現了沖突,這個接口“類型”并不是 Golang 中的“類型”。事實上,我在這里使用了一個叫做 ??interfaceType?? 的 Go 類型來代表接口類型。呼,我花了一分鐘才弄明白!

然后,假設接口的類型正確,我們就可以調用 ??c.StationInfo(x)??? 來檢索基站信息,??StationInfo()??? 方法可以獲取到關于這個接口 ??x?? 的信息。

這將返回一個包含 ??*StationInfo??? 指針的切片。我不大確定這里為什么要用切片,或許是因為接口可能返回多個 ??StationInfo????不管怎么樣,我都可以遍歷這個切片,然后使用之前提到的 ??+%v??? 技巧格式化打印出 ??StationInfo?? 結構的屬性名和屬性值。

運行上面的程序后,我得到了下面的輸出:

&{HardwareAddr:70:5a:9e:71:2e:d4 Connected:17m10s Inactive:1.579s ReceivedBytes:2458563 TransmittedBytes:1295562 ReceivedPackets:6355 TransmittedPackets:6135 ReceiveBitrate:2000000 TransmitBitrate:43300000 Signal:-79 TransmitRetries:2306 TransmitFailed:4 BeaconLoss:2}

我感興趣的是 ??Signal???(信號)部分,可能還有 ??TransmitFailed???(傳輸失敗)和 ??BeaconLoss??(信標丟失)部分。信號強度是以 dBm(分貝-毫瓦decibel-milliwatts)為單位來報告的。

簡短科普:如何讀懂 WiFi dBm

根據 ??MetaGeek?? 的說法:


  • -30 最佳,但它既不現實也沒有必要
  • -67 非常好,它適用于需要可靠數據包傳輸的應用,例如流媒體
  • -70 還不錯,它是實現可靠數據包傳輸的底線,適用于電子郵件和網頁瀏覽
  • -80 很差,只是基本連接,數據包傳輸不可靠
  • -90 不可用,接近“背景噪聲noise floor”

注意:dBm 是對數尺度,-60 比 -30 要低 1000 倍。

使它成為一個真的“掃描器”

所以,看著上面輸出顯示的我的信號:-79。哇哦,感覺不大好呢。不過單看這個結果并沒有太大幫助,它只能提供某個時間點的參考,只對 WiFi 網絡適配器在特定物理空間的某一瞬間有效。一個連續的讀數會更有用,借助于它,我們觀察到信號隨著樹莓派的移動而變化。我可以再次修改 ??main?? 函數來實現這一點。

var i *wifi.Interface

for _, x := range interfaces {
if x.Type == wifi.InterfaceTypeStation {
// Loop through the interfaces, and assign the station
// to var x
// We could hardcode the station by name, or index,
// or hardwareaddr, but this is more portable, if less efficient
i = x
break
}
}

for {
// c.StationInfo(x) returns a slice of all
// the staton information about the interface
info, err := c.StationInfo(i)
if err != nil {
fmt.Printf("Station err: %s\n", err)
}

for _, x := range info {
fmt.Printf("Signal: %d\n", x.Signal)
}

time.Sleep(time.Second)
}


首先,我命名了一個 ??wifi.Interface??? 類型的變量 ??i??。因為它在循環的范圍外,所以我可以用它來存儲接口信息。循環內創建的任何變量在該循環的范圍外都是不可訪問的。

然后,我可以把這個循環一分為二。第一個遍歷了 ??c.Interfaces()??? 返回的接口切片,如果元素是一個 ??Station??? 類型,它就將其存儲在先前創建的變量 ??i?? 中,并跳出循環。

第二個循環是一個死循環,它將不斷地運行,直到我按下 ??Ctrl + C?? 來結束程序。和之前一樣,這個循環內部獲取接口信息、檢索基站信息,并打印出信號信息。然后它會休眠一秒鐘,再次運行,反復打印信號信息,直到我退出為止。

運行上面的程序后,我得到了下面的輸出:

[chris@marvin wifi-monitor]$ go run main.go
Signal: -81
Signal: -81
Signal: -79
Signal: -81

哇哦,感覺不妙。

繪制公寓信號分布圖

不管怎么說,知道這些信息總比不知道要好。讓樹莓派連接上顯示器或者電子墨水屏,并接上電源,我就可以讓它在公寓里移動,并繪制出信號死角的位置。

劇透一下:由于房東的接入點在隔壁的公寓里,對我來說最大的死角是以公寓廚房的冰箱為頂點的一個圓錐體形狀區域......這個冰箱與房東的公寓靠著一堵墻!

我想如果用《龍與地下城》里的黑話來說,它就是一個“沉默之錐Cone of Silence”。或者至少是一個“糟糕的網絡連接之錐Cone of Poor Internet”。

總之,這段代碼可以直接在樹莓派上運行 ??go build -o wifi_scanner??? 來編譯,得到的二進制文件 ??wifi_scanner?? 可以運行在其他同樣的ARM 設備上。另外,它也可以在常規系統上用正確的 ARM 設備庫進行編譯。

祝你掃描愉快!希望你的 WiFi 路由器不在你的冰箱后面!你可以在 ??我的 GitHub 存儲庫?? 中找到這個項目所用的代碼。

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2019-03-31 08:00:02

樹莓派更新樹莓派 Linux

2019-03-24 20:30:18

樹莓派Linux

2020-07-25 09:00:12

樹莓派WiFi相框Linux

2019-03-12 18:33:57

樹莓派Linux

2022-02-11 09:24:05

樹莓派OpenWrt固定IP服務

2021-07-25 10:30:04

樹莓派Linux

2019-03-23 19:33:14

樹莓派Linux操作系統

2019-03-28 18:51:52

樹莓派Linux編程語言

2021-06-15 15:00:08

Cockpit樹莓派Linux

2019-04-11 11:40:32

樹莓派編程語言Linux

2019-08-20 15:38:19

樹莓派Linux

2017-10-09 09:33:55

2019-03-26 09:00:43

樹莓派編程Linux

2021-03-29 21:24:40

樹莓派Linux

2017-10-30 16:12:30

DockerServerless樹莓派

2018-03-26 12:35:23

樹莓派Pi-hole攔截廣告

2018-10-12 11:20:20

樹莓派NAS Linux

2021-11-14 05:00:56

排查Sdk方式

2018-05-09 13:03:29

Linux樹莓派顆粒物

2020-07-16 21:00:05

樹莓派Kubernetes集Linux
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜影院网站 | 波多野结衣电影一区 | 成人不卡一区二区 | 亚洲日韩中文字幕一区 | 夜夜草天天草 | 日本在线视频一区二区 | 91视频电影 | 日韩视频一区二区 | 亚洲精品免费视频 | 亚洲一区视频在线 | 九九亚洲| 久久综合狠狠综合久久 | 99久久国产 | 美女视频一区二区三区 | 免费黄篇 | 999热在线视频 | www国产亚洲精品久久网站 | 在线a视频 | 精品久久久久久久久久久下田 | 日韩欧美在线视频 | 午夜影院在线观看视频 | 中文字幕中文字幕 | 国产成人免费视频网站高清观看视频 | 殴美黄色录像 | 97国产一区二区 | 久久久网 | 久久精品久久精品久久精品 | 人人做人人澡人人爽欧美 | 亚洲激情第一页 | 欧美电影大全 | 男人天堂免费在线 | 亚洲女人天堂网 | 亚洲精品国产成人 | 久久久久久艹 | 天久久 | 精品日韩电影 | 国产欧美日韩一区 | 久久一二| 欧美精品国产精品 | 免费国产精品久久久久久 | 在线欧美亚洲 |