如何判断是否联网
如何判断是否联网
来源 https://www.zhihu.com/question/378097272
=================
作者:Luv Letter
链接:https://www.zhihu.com/question/378097272/answer/1090722455
简单解释, 当你的操作系统连接特定 HTTP 服务, 比如 http://www.gstatic.com/generate_204, 如果能够返回 204 状态码, 那就基本说明你连接上网络了. 如果被 301, 说明你已经有 IP, 但是你的网络可能是一个付费网络, 会跳转到一个页面让你付钱/登陆. 如果无法解析域名/创建 TCP 连接, 说明你的三层/四层网络存在问题, 再下去多半是网线没插之类的物理层问题.
至于 TCP/UDP(一般主要是为了 DNS) 无法创建, 有可能是因为没路由, 或者是 SYN 过去没包回来超时, 或者是 SYN 飞过去, 中间路由 ICMP 告诉你目标不可达; 如果是创建 socket 失败说明可能没三层 IP, 没 IP 可能是因为没网卡/没插网线/二层里没有 DHCP 或者没有设置 IP.
=================
作者:6IE闫辉
链接:https://www.zhihu.com/question/378097272/answer/1321637248
http://www.msftncsi.com/ncsi.txt
中文意思:网络连接状态指示器,是Windows系统判断某一台机器是否能够连接到Internet的技术。
https://blogs.technet.microsoft.com/networking/2012/12/20/the-network-connection-status-icon/
1. NCSI首先向http://dns.msftncsi.com发出一次DNS查询
2. 发出获取 http://www.msftmcsi.com/ncsi.txt 内容的 HTTP GET 请求。这是请求访问文件
3. 向 http://dns.msftncsi.com 发出 DNS 查询。
=================
链接:https://www.zhihu.com/question/378097272/answer/1088144113
Win10在连接到网络的时候,会访问 http://www.msftconnecttest.com/connecttest.txt ,然后看访问结果来判断是不是已经连接到互联网了。这个机制叫 NSCI(Network Connection Status Indicator)。
macOS和Linux(Gnome)也都有类似的机制。而且Android等移动操作系统也是有类似的机制的。
值得注意的是,有的浏览器也有NCSI机制,比如Firefox就用 http://detectportal.firefox.com/success.txt 来做NCSI。
NCSI除了可以判断是否联网外,可以做检测captive portal并弹出认证窗口。(比如校园网的登录机制等等)
第二个问题就是标题中的问题了:
电脑是怎么知道它自己已经联上网了?
这个其实很简单,不管是无线连接、还是有线连接,连接这个动作都是操作系统主动发起的,操作系统当然知道连接的结果啊。
当然这个原理就比较复杂了,首先是物理层和链路层,比如WiFi的认证;然后是网络层和运输层,确保tcp/udp能够收发。最后各个程序还有自己的应用层代码,比如IE的NCSI实现。
=================
链接:https://www.zhihu.com/question/378097272/answer/1093221721
Windows这部分功能叫NCSI(網路連接狀態指示器),方式大概是访问http://www.msftconnecttest.com/connecttest.txt 这个地址,返回Microsoft Connect Test这个字串就证明网络正常。
这里有详细的说明
>
Windows 10 和更新版本:
- NCSI 發送 DNS 請求以解析
www.msftconnecttest.com
FQDN 的位址。 - 如果 NCSI 收到來自 DNS 伺服器的有效回應,NCSI 會向 發送普通 HTTP GET
http://www.msftconnecttest.com/connecttest.txt
請求。 - 如果 NCSI 成功下載文字檔,它將確保該檔案包含
Microsoft Connect Test
。 - NCSI 發送另一個 DNS 請求來解決
dns.msftncsi.com
FQDN 的位址。
- 如果這些請求中的任何一個失敗,網路警報將顯示在工作列中(如症狀中所述)。 如果將滑鼠懸停在圖示上,則會看到一條消息,如「無連線」或「有限的連線」(具體取決於哪些請求失敗)。
- 如果所有這些請求都成功,工作列將顯示通常的網路連線圖標。 如果將滑鼠懸停在圖示上,則會看到一條消息,如「網際網路連線」。
安卓系统也是一样的,只是安卓是靠204这个状态码而不是特定的字符串,并且对于安卓系统这个地址是可以改的,设置项是captive_portal_http_url
,需要进shell用settings
命令去修改。常常有人从国外带回来机器,或者自己刷了第三方ROM发现一直提示没有网络但是还能正常联网,就是因为这个地址安卓默认用的是用谷歌的服务(或者一些比较老的cm ROM,默认设置的提供204响应的服务器已经关了)
adb shell settings put global captive_portal_http_url https://www.google.cn/generate_204
adb shell settings put global captive_portal_https_url https://www.google.cn/generate_204
详细信息可以参考这篇文章
=================
用curl命令模拟上网认证请求
这个要去分析上网认证的请求方式及参数,比较麻烦,作为最后的备选方案。
利用firefox编辑重发的功能获取请求方法及参数
上网认证地址:http://172.16.4.254/webAuth/index.htm?www.gstatic.com/generate_204
(1)在浏览器输入上网认证地址,打开firefox浏览器控制台并选择网络,输入账号密码进行上网认证。
(2)点击浏览器的控制台的重发功能,选择“编辑重发”
这里可以看到上网认证请求的方法及参数
(3)使用curl进行上网认证
curl http://172.16.4.254/webAuth/index.htm?www.gstatic.com/generate_204 -X POST -d “username=用户名&password=这里是密码&pwd=这里是密码&secret=true”
至此,已经在虚拟机命令行完成了上网认证,可以愉快在虚拟机访问互联网了。
============== End