Wi-Fi、藍牙與 DNS

Wi-Fi 登入頁面、藍牙音訊爆音,以及每個網路最快的 DNS。

藍牙音訊:AirPods 為什麼有雜音

AirPods 或其他藍牙耳機、喇叭播放時,Kilobat 每五秒檢查一次 Mac 這一端有哪些因素可能造成雜音或斷音。藍牙在 2.4 GHz 頻段內跳頻,並與 Wi-Fi 共用無線電,因此它會查看:Mac 的 Wi-Fi 是否使用 2.4 GHz;該頻道是否被鄰居的網路擠滿(依據最近半小時內的 Wi-Fi 掃描;聆聽時 Kilobat 從不掃描,因為掃描本身就可能讓音訊跳音);AirDrop 連結(AWDL)是否忙碌,以及是 AirDrop、通用控制還是 Sidecar 讓它保持忙碌;Wi-Fi 上是否有 2.5 MB/s 或以上的流量,以及流量最大的 App;耳機的藍牙訊號是否在 −72 dBm 或更弱;以及是否另有四個或以上藍牙裝置已連接。它透過 Core Audio 讀取 macOS 的聲音輸出,不需要任何權限,並會留意耳機麥克風是否也已開啟:此時 macOS 會改用音質較低的免持模式,更容易斷斷續續。訊號和其他裝置需要藍牙權限,只有在你按下「檢查藍牙」時才會要求。

有干擾時,「健康狀態」會顯示一行該改什麼,效果最好的排在前面:加入路由器的 5 GHz 網路(如果 macOS 記得範圍內的某個網路,會提供按鈕,名稱與 2.4 GHz 網路相同時也一樣)、把路由器設為頻道 1、6 和 11 中最空閒的一個、暫停 AirDrop(提供按鈕;macOS 會要求輸入你的密碼,聲音停止五分鐘後或一小時後 AirDrop 會恢復)、暫停大型下載,以及靠近一點或別把 Mac 放在包包裡。通話時它還會建議使用 Mac 本身的麥克風,這樣耳機能維持高音質。Kilobat 無法聽到聲音本身:藍牙音訊斷斷續續時,macOS 不會通知其他 App,所以建議來自當前條件,並會如實說明。在這一行或「健康狀態」的「附近」面板中按下有雜音即可告訴 Kilobat;它會記下當時的干擾因素,如果當時沒有干擾,就會告訴你較可能的原因是距離或耳機本身的連線。每次聆聽最多通知一次,僅在兩個以上原因同時持續 20 秒時發出,且每四小時最多一次;可在「設定」›「監控」中關閉。以上全部免費。使用 Pro 時,如果你在 Wi-Fi 使用 2.4 GHz 或 AirDrop 正在掃描時透過藍牙耳機聆聽通話,這次通話的成績單上會多一行說明。在終端機中,kilobat bluetooth audio 會執行相同的檢查(App 執行時還會加入訊號和流量最大的 App),代理程式則可透過 get_bluetooth_audio 讀取。

「健康狀態」›「本機連線」會在連線速度旁顯示 Mac 與路由器協商的設定:頻道、頻段和頻道寬度、Wi-Fi 標準(Wi-Fi 4、5、6、6E 或 7,含 802.11 名稱)、安全性(例如 WPA2 個人級或 WPA3 個人級)以及 Mac 的傳送強度。舊標準或 5 GHz 上的 20 MHz 頻道會限制連線速度,無論訊號多強都一樣。

開放式網路的安全性會以紅色顯示,並附一行說明其意義(Wi-Fi 本身沒有密碼和加密;使用 HTTPS 的網站和 App 仍受加密保護);WEP 和第一代 WPA 也會以紅色顯示,因為它們已過時且會降低 Wi-Fi 速度。Enhanced Open 不需密碼即可加密。「雷達」中的附近網路會顯示各自提供的最高安全性。在終端機中,kilobat wifi status 列印相同資訊;CoreWLAN 提供時,--json 會加入 widthMHz、standard、phyMode、security、securityLevel(強、良好、弱或開放)、securityNote、transmitPowerDBm 和 countryCode(MCP:get_wifi)。kilobat scan --json 和 scan_wifi 會加入各網路的 security 和 securityLevel。

Wi-Fi 登入頁面

飯店、咖啡廳、機場和共同工作空間的 Wi-Fi 常會攔住所有連線,直到你在它自己的頁面上登入,過一小時或一天後又會讓你登出。Kilobat 用和 macOS 與 Android 相同的方式檢查這個頁面:向 captive.apple.com 傳送一個普通的 http 請求,它會回答「Success」;如果失敗,再請求 Google 的 connectivitycheck.gstatic.com/generate_204。如果收到重新導向或任何其他頁面,就表示有登入頁面擋在中間,Kilobat 會記下該頁面的位址,不論網路是透過重新導向、meta refresh 還是指令碼傳送。它會在你加入網路時、網際網路檢查失敗時,以及登入頁面出現期間檢查,其餘時間每 5 到 15 分鐘檢查一次,絕不密集輪詢。除了這兩個位址,不會傳送任何東西到任何地方。

它能分辨三種情況:完全沒有網際網路、網路要求你登入,以及網路讓你登出了(你曾在該網路上登入,而同一個登入頁面又出現了)。選單列彈出式視窗會為此顯示一列:「這個 Wi-Fi 需要你登入」和打開登入頁面,或「Wi-Fi 登入頁面已讓你登出」和重新登入。如果你在「這個地點」卡片上為地點命名,這一列會使用該名稱,例如「The Long Table 的 Wi-Fi 已讓你登出」。標題列仍顯示「需要登入」,Wi-Fi 選單顯示「已登出 · 請重新登入」。Kilobat 絕不會自行打開瀏覽器,也不會干涉加入網路時 macOS 顯示的登入視窗。它是為了那個視窗沒有出現的時候而準備,也供之後使用。

當登入頁面擋在中間時,「健康狀態」只會給出這一個原因:「Wi-Fi 登入頁面已讓你登出」並提供「重新登入」,或「需要登入網路」並提供「打開登入頁面」,不再怪罪 DNS、ping 遺失或業者。事件記錄會記為 Wi-Fi 登入而不是斷線,因此在給業者的報告中不會算作斷線,也不會觸發「無法連線」提醒。卡頓過的通話會說明它是在 Wi-Fi 登入頁面讓你登出後卡頓的。到網際網路的卡頓測試會說是登入頁面攔住了連線,而不是沒有任何回應。「為什麼連不上?」和 kilobat why 會說是 Wi-Fi 登入頁面擋在中間,而不是回報 DNS 或 TLS 錯誤。

Kilobat 也會了解每個網路上一次登入能維持多久。它會記下登入何時開始、檢查結果何時從登入頁面變成 Success,以及登入頁面何時再次出現。通常時長是它從頭到尾不間斷看到的工作階段的中位數,至少需要兩次。如果登入頁面本身明確寫出唯一的時長,例如「1 hour of free Wi-Fi」(僅限英文頁面),一次工作階段就夠了。因睡眠、離開網路或重新連線而中斷的工作階段不計入,而且每次工作階段都以最後一次成功的檢查為終點,所以估計值寧短勿長。歷史記錄依網路保存,連同「這個地點」的名稱,存放在這台 Mac 的 ~/Library/Application Support/Kilobat/captive-portals.json 中,絕不會傳送到任何地方。

有了 Kilobat Pro,這一列會顯示「已登入 · 剩餘約 40 分鐘」,並在登入通常到期前約五分鐘發出通知:「Café Wi-Fi 將在 5 分鐘後讓你登出」(如果是你命名過的地點,則是「The Long Table 的 Wi-Fi 將在 5 分鐘後讓你登出」),並提供「打開登入頁面」。如果它仍在中途讓你登出,「Café Wi-Fi 已讓你登出」會告訴你網際網路並沒有斷線,並提供「重新登入」。每次登入只提醒一次,這類通知每 20 分鐘最多一則;加入網路時不會通知,因為 macOS 會顯示自己的視窗。可在「設定」›「監控」›「Wi-Fi 登入到期前提醒」中關閉。

偵測登入頁面、這一列、「打開登入頁面」以及「健康狀態」中的登出原因都免費;「健康狀態」的完整發現列表仍屬於 Pro。登入時長會為所有人記錄,剩餘時間和提醒則屬於 Kilobat Pro。在終端機中,kilobat portal 會立即檢查並輸出狀態(open、portal 或 offline)、隱藏查詢參數值的登入頁面位址、這個網路的狀態、它通常的登入時長,以及每個網路的歷史記錄:名稱、「這個地點」的名稱、登入頁面的主機、看到的工作階段、通常時長和最後一次看到的時間。kilobat portal open 會在瀏覽器中打開登入頁面。代理程式透過 get_captive_portal 讀取相同的 JSON。如果登入頁面一直沒有出現,請參閱飯店 Wi-Fi 登入頁面。

這裡可以投放或列印嗎?

加入網路數秒後,以及在「健康狀態」按再次檢查時,Kilobat 會透過 Bonjour 搜尋三秒,找出可投放或列印的裝置:Chromecast 和內建 Chromecast 的電視(_googlecast._tcp)、Apple TV、AirPlay 電視與喇叭(_airplay._tcp、_raop._tcp)及印表機(_ipp._tcp、_ipps._tcp、_printer._tcp),不包括這部 Mac 自身的 AirPlay 接收器。有裝置回應時,「健康狀態」的「投放與列印」面板和 Wi-Fi 選單會顯示「投放與列印應可使用:找到客廳電視、HP LaserJet」。

沒有裝置回應時,Kilobat 會檢查其他裝置是否有任何回應:向 Mac 所在 /24 範圍內的每個私有位址傳送一個空封包、檢查鄰居快取、向最多六個鄰居各傳送一次 ping,以及檢查接續互通記錄。如果有位址以路由器的硬體位址回應(代理 ARP),則提示網路可能隔離裝置。代理 ARP 也用於一般路由,因此這只是可能的原因,絕不能證明投放或列印受到阻擋。沒有結果的掃描、大型子網路或登入頁面本身都無法確認隔離。否則會顯示「未看到投放裝置」,並說明哪些項目有回應及仍有哪些不確定之處。在飯店或咖啡廳 Wi-Fi 上,判斷也會顯示在登入列旁。--quick 會重新瀏覽 Bonjour 並讀取快取,不會掃描或 ping 其他裝置。Bonjour 和裝置探測僅限本機網路;當 App 無法回應時,獨立 CLI 也會執行一般的網際網路連通性及登入頁面檢查,以辨識裝置設定用 Wi-Fi。macOS 第一次會要求本機網路存取權。

當 Mac 加入沒有外部網際網路的裝置專用 Wi-Fi,例如印表機的 Wi-Fi Direct(DIRECT-xx-HP …、HP-Setup…、Brother 的 …_BRxxxx、Canon 的 …series)、Sony 或 Canon 攝影機、GoPro(GP 加八位數字)、Insta360 或 Ricoh Theta(….OSC)、DJI Tello 或 Spark,或 Shelly、Tasmota、Kasa、Tapo 或 WiZ 設定網路時,Kilobat 會顯示「你已連上印表機專用的 Wi-Fi;此網路原本就沒有網際網路。」彈出式視窗標題顯示「裝置 Wi-Fi」,不會出現「無法連線」警示,事件記錄記為「裝置 Wi-Fi」而非網路中斷;按返回會使用 macOS 儲存的密碼重新加入先前使用的 Wi-Fi。名稱來自製造商手冊;名稱相符但可連上網際網路的網路會被視為一般 Wi-Fi。

當 Mac 使用 AirPlay(聲音輸出為 AirPlay 接收器,或 macOS 的 AirPlay 傳送端在本機網路上串流),或 Chromium 瀏覽器傳送足夠的本機流量而可能正在投放時,「健康狀態」會顯示 Mac 端可能造成卡頓的因素:Mac 使用 2.4 GHz、訊號弱(−70 dBm 或更弱)、AirDrop 掃描(AirPlay 本身使用 AirDrop 連線時除外),以及另一個 App 以 2.5 MB/s 傳輸或以 1.25 MB/s 上傳。按鈕可加入記住的 5 GHz 網路、暫停 AirDrop 直到投放結束或一小時後,以及透過 Kilobat Pro 比照通話模式暫停同步與下載 App。Kilobat 看不到掉格或電視自身的訊號,並會說明這點。在終端機中:kilobat local check [--quick] [--json];AI 代理程式使用 MCP 工具 check_local_network。

停留在較遠的 Mesh 節點

Mac 要等到 Wi-Fi 存取點的訊號降至約 -75 dBm,且另一個存取點強 12 dB 時才會切換。因此在 Mesh 系統中,它常常一直連接樓下加入的節點,而房間裡的節點閒置:這就是常見的「樓上 Wi-Fi 很慢」。Kilobat 會發現這一點,並在「健康狀態」中提示:「目前連接客廳節點,訊號為 -78 dBm;辦公室節點為 -52 dBm。」旁邊和 Wi-Fi 選單中的「重新連接」會讓 Mac 切換:它先用網路儲存的密碼直接加入較近的節點;如果失敗,則關閉再開啟 Wi-Fi,讓 macOS 自行選擇最強節點。Wi-Fi 會中斷幾秒,因此通話期間 Kilobat 會先詢問。之後它會說明 Mac 最終連接的位置:「現在連接辦公室節點,訊號為 -52 dBm。」

只有同時符合以下條件時才會提示:你的訊號弱於 -65 dBm;同一網路的另一個節點在 Mac 支援的頻段上至少強 15 dB;該節點估計的連結速率至少為目前的 1.5 倍,估算依據為訊號和頻道寬度。最後一條規則避免頻段引導產生多餘提示:強 2.4 GHz 訊號不一定優於良好的 5 GHz 連線。上述情況必須持續兩分鐘、至少經過三次讀取,且自身訊號穩定,因此在家中走動或正在漫遊時不會計入。Kilobat 透過一般背景檢查讀取無線電,僅在訊號較弱時掃描你的網路,最多每兩分鐘一次,通話期間絕不掃描。無線電依位址分組為節點;在「健康狀態 › Wi-Fi 節點」中可為每個節點命名,例如「辦公室」,檢查結果會使用這些名稱。通話在較遠節點上卡住時,通話報告會註明節點(Pro)。開啟「設定 › 監控 › Mac 持續連接較遠的 Wi-Fi 節點時通知我」後,持續五分鐘會收到一次通知,每六小時最多一次。兩週內發生三次時,Kilobat 會建議檢查 Mesh 系統的引導或漫遊設定,或移動節點以減少覆蓋重疊。

macOS 只向擁有定位權限的 App 顯示存取點位址,因此此功能需要該權限;位置資訊保留在 Mac 上。除非 Wi-Fi 設定 › 進階要求輸入管理員密碼,否則加入網路和關閉再開啟 Wi-Fi 都不需要密碼。在終端機中,kilobat wifi nodes 列出節點,kilobat wifi nodes name <id> Office 為節點命名,kilobat wifi reconnect 切換 Mac 的節點(CLI 0.31);AI 代理程式讀取 get_wifi_nodes,呼叫 reconnect_wifi 前會詢問。

每個網路最快的 DNS

在家最快的 DNS,到了咖啡廳往往不是最快的。Kilobat 會悄悄地針對每個網路找出答案,使用 Kilobat Pro 時還會在你加入網路時切換過去。「健康狀態」›「DNS」會顯示結果:「此處最快:Quad9(12 ms,你的網路 DNS 為 48 ms)」或「此處你網路的 DNS 最快」,並列出最近一次測量中的每個解析器。

比較什麼。你網路本身的 DNS(也就是路由器或業者分配的那個),與 Cloudflare(1.1.1.1)、Quad9(9.9.9.9)、Google(8.8.8.8),以及你在「設定」›「網路」›「要測試的解析器」中依 IP 位址加入的任何解析器比較。在那裡排除某個解析器後,Kilobat 絕不會測量或選擇它。每個解析器都附有一行說明,介紹它會保留哪些資料:例如 Google 會保留你的 IP 位址最長 48 小時。較快的解析器不代表較注重隱私。

營運者及所在地。 每個解析器都根據營運者自己的頁面顯示營運者及其適用法律所屬國家:Cloudflare · 美國、Quad9 · 瑞士、Google · 美國;你新增的位址則包括 AdGuard · 賽普勒斯、OpenDNS(Cisco)· 美國及 DNS4EU · 捷克。網路本身的 DNS 顯示為「你的供應商」,Kilobat 不認識的位址顯示為「未知營運者」;絕不根據位址猜測。

各解析器的表現。 在最近一次執行結果下方,「健康狀態」›「DNS」會以每天一個方格顯示各解析器在此網路過去 14 天的表現:查詢獲得回應的比例,並標記部分失敗或回應緩慢(超過 200 ms)的日子。資料來自相同的背景執行,因此不增加額外負擔。

如何測量。每個網路每天最多三次,間隔至少四小時,並在 Mac 本身流量較少時進行,Kilobat 會直接向每個解析器查詢十個熱門網站,各查詢兩次:第一次回應是你最近沒開過的網站需要等待的時間,第二次則是解析器本身的往返時間。它也會查詢一個不可能存在的名稱,找出仍然回應的解析器(NXDOMAIN 改寫,通常是為了顯示廣告),並查詢三個由 CDN 提供的網站,再測量連到各解析器給出位址的 TCP 連線,與連到你網路 DNS 給出位址的連線比較。若解析器把你帶到明顯更遠的 CDN 節點,會被罰以額外連線時間的三倍,因為每個連線都要在交握、TLS 和第一個請求中付出這段時間:查詢快卻讓瀏覽變慢的解析器不會勝出。一次測量約為每個解析器二十幾次小型查詢和幾次連線,只需幾 KB。它絕不會在計量網路或手機熱點上、透過 VPN、在 Wi-Fi 登入頁面之後或在低耗電模式下執行。立即測試可馬上執行一次。

何時選擇。只有當某個解析器在至少三個不同日子的最近幾次測量中,中位數都比你網路本身的 DNS 快至少 20 ms,且第 90 百分位數更低時才會選擇。在那之前,仍使用你網路本身的 DNS。一旦選中,只要它仍有任何領先就會保留;當它有三天沒有領先時,會讓位給網路本身的 DNS,查詢失敗時則立即讓位。領先 20 ms 才切換,降到 0 才退出,因此不會來回切換。

切換。 在「健康狀態」›「DNS」開啟在此網路使用最快的 DNS,或在「設定」›「網路」中為所有網路開啟。Kilobat 透過其輔助程式設定網路服務的 DNS;這與闔上螢幕時保持 Mac 運作的輔助程式相同,因此不必每次輸入密碼,只需在「登入項目」允許一次。VPN 連線時、設定描述檔或 App 的加密 DNS 決定查詢時,以及等待 Wi-Fi 登入頁面時,Kilobat 絕不切換,因為登入頁面需要網路本身的 DNS。你自行設定的 DNS 伺服器絕不會被更動。Kilobat 只會還原自己的變更,並在 VPN 連線、離開網路、結束 Kilobat,及網路本身有回應但查詢連續失敗兩次時還原(該解析器接著會在該網路上等待一天)。在「健康狀態」›「DNS」的失敗時使用或「設定」›「網路」›「備用 DNS」選擇備用解析器後,解析器失敗時會立即切換至備用解析器,但僅限它當下有回應;若備用解析器也失敗,就會恢復網路本身的 DNS,避免 Mac 沒有可用的 DNS。每次切換都會記錄在「歷史記錄」,並在 Wi-Fi 選單顯示為「DNS:Cloudflare(此處最快)」,附有復原按鈕,可還原網路的 DNS 並關閉該網路的自動切換。

測量和結果免費;自動切換屬於 Kilobat Pro。在終端機中,kilobat dns fastest 顯示此網路的結果(--all 顯示所有網路,--json 供指令稿使用),kilobat dns auto on|off [--network <name>] 開啟或關閉切換,kilobat dns exclude|include <resolver> 排除解析器或新增自訂解析器,kilobat dns fallback <resolver>|off 設定備用解析器。輸出會列出各解析器的營運者及所在地,以及各自在 14 天內獲得回應的查詢。AI 代理程式以 get_fastest_dns 讀取;set_fastest_dns 和 set_dns_fallback 會先詢問你。