最近几天遇到了比较奇葩的状况,电脑正常上网中,等离开房间过一会儿再回来,突然发现网页全部无法打开,一开始以为是浏览器崩溃了,然而换了IE、谷歌浏览器、搜狗浏览器、360浏览器之后均发现是一样的情况,于是再看看电脑右下角的网络链接状态图标,发现处于正常状态,没有红叉叉,那么便也排除了网线脱落的因素。究竟是何原因引发的突然断网,接下来请跟随我的脚步来一探究竟吧。
针对断网情况的排查可以由外至内开展,首先确认家中的路由器是否可以正常联网,由于我的台式电脑是通过网线连接至路由器,手机是通过接入路由器的Wifi热点进行联网,那么先检查下手机的网络状态,发现可以正常打开网页、收发微信的信息,这说明家中路由器工作状态正常,外网没有出现断网的情况,那么接下来便开始排查电脑端。
通过ping命令,我们可以向特定的目的主机发送请求报文,用于测试从本机到目标主机的网络状况是否正常,这里我们可以ping一下百度的服务器:开始——运行——输入cmd,在弹出的CMD命令行窗口中输入以下命令(ping和www.baidu.com之间为空格):
ping www.baidu.com
ping命令执行结果如上图,可以看到收到了百度服务器的响应,说明我们的网络连接是通畅的。
上一步ping命令的检查正常只能说明网络是通畅的,但是我们用浏览器访问网页是通过域名进行访问的,如 http://www.baidu.com ,域名是需要通过DNS进行解析方可访问最终的目标主机,如果DNS无法正常进行解析,那么网页也将无法被正常打开,这种情况就是我们碰到的最常见情况:“打不开网页但是可以上QQ”,接下来我们便可以使用nslookup命令检查DNS的解析情况,在CMD窗口中输入以下命令(nslookup和www.baidu.com之间为空格):
nslookup www.baidu.com
nslookup命令执行结果如上图,可以看到DNS解析使用的是我们本地的路由器地址192.168.2.1提供的DNS解析服务,已经成功的将 baidu.com 的域名解析至ip为 14.215.177.38 和 14.215.177.39 的服务器,说明DNS解析工作正常。
这下就有点头疼了,通常我们遇到的情况是可以ping通但是dns无法解析,其解决方案是将电脑ip配置信息中的dns服务器改为互联网上公用的dns服务器如:8.8.8.8 、114.114.114.114,这是由于114.114.114.114是国内移动、电信和联通通用的DNS,解析成功率相对来说更高,国内用户使用的比较多,速度相对快、稳定,是国内用户上网常用的DNS。8.8.8.8是GOOGLE公司提供的DNS,该地址是全球通用的,相对来说,更适合国外以及访问国外网站的用户使用。由于通过上述nslookup命令的测试已经说明了DNS解析正常,所以这里我就没有必要再去修改DNS设置了,直接进行其他方面的排查。
由于最初我发现突然断网的情况是在离开电脑一阵子后再次回来使用的时候出现的,这让我怀疑是否是因为较长时间没有上网导致计算机为了省电自动将网卡进入了睡眠模式,于是检查一下网卡的配置状态,步骤为:控制面板——网络和Internet——网络和共享中心——更改适配器设置,检查网卡属性“电源管理”选项卡中的“允许计算机关闭此设备以节约电源”是否被勾选了,如果被勾选了需要将其去掉。
当我取消此处的勾选之后,将网卡禁用然后又启用,竟然发现还是不起作用,无奈只好采用重启大法,当计算机重启之后发现竟然可以上网了,于是心中一番窃喜,然而好景不长,没过多久又无法上网了,真是让人捉急。。。
通过多次尝试,发现每次出现突然不能上网的情况之后,重启电脑便可以恢复正常,但是使用一阵子过后,很大概率又会断网,仍然无法找到问题根源所在,想了一下不如将网络进行重置试一试,通过在CMD窗口输入命令 netsh winsock reset 执行:
netsh winsock reset
这个命令的作用是重置 Winsock 目录。如果一台机器上的Winsock协议配置有问题的话将会导致网络连接等问题,就需要用netsh winsock reset命令来重置Winsock目录借以恢复网络。这个命令的好处是可以重新初始化网络环境,以解决由于软件冲突、病毒原因造成的参数错误问题。该命令执行后计算机会提示重启,完成重启操作后发现电脑又可以正常上网了。
然而理想很丰满,现实很骨感。本以为重置网络恢复了初始设置后即可搞定断网问题,没想到过阵子居然又断网了,没错!你没有看错!连网络环境都重置了的情况下居然还是没有解决问题!这恐怕是从业以来碰到过的最奇葩问题了!心中一万只艹泥马奔腾而过!
突然,我脑海中灵光一现,之前我们已经尝试过使用ping命令检查网络连通状态,现在不妨搭配使用telnet命令检查端口访问状态。实践中,ping和telnet命令往往是搭配使用,ping命令用于检测目标服务器是否处于正常运行状态,telnet命令用于确认目标服务器端口是否开放,二者搭配起来用于测试客户端与目标主机间的网络通信状态是否正常。
这里以百度网站为例,百度首页网址 http://www.baidu.com 使用的是Web服务器的默认端口80,那么我们执行命令:telnet www.baidu.com 80 用来测试本机至百度网站的80端口是否通信正常(注意参数之间要有空格):
telnet www.baidu.com 80
执行结果让我大吃一惊,端口访问失败了!!!一般情况下我们 telnet 目标主机出现连接失败的情况是由于目标主机对应端口所运行的服务出现了异常才无法访问,你要说是百度的网站服务宕机了导致我们 telnet 不通??这也太不可能了,于是我赶紧掏出手机访问了一下百度,果然还是正常访问的。那么这下找总算找到问题出在哪里了,为什么这么说?下面让我们来看一张图便知晓。
这里先看一下关于ping命令的介绍:Ping是工作在 TCP/IP网络体系结构中应用层的一个服务命令, 主要是向特定的目标主机发送 ICMP(Internet Control Message Protocol 因特网报文控制协议)Echo 请求报文,测试目的站是否可达及了解其有关状态。
根据上图中OSI的七层模型和其简化版的TCP/IP模型,我们可以看到 telnet 命令和 ping 命令(ICMP协议)分别工作在TCP/IP模型定义的应用层和网际层,那么结合我们之前测试的结果:ping 成功 telnet 失败,我们可以得出结论为:网络层是正常的,问题出在应用层。这下终于可以解释了为什么前面那么多的尝试最终都没有解决问题,那是因为前面的各种措施几乎都是在针对于网络层面的问题进行处理,网络层本来就是正常的,所以再怎么折腾也是枉然。
既然问题已经定位在了应用层,那么我们便去看看Windows的日志,在计算机“我的电脑”图标中点击右键,进入“计算机管理”后,展开“Windows日志”下面的“系统”节点,便可以查看最近的系统日志。
在当天的记录中,可以看到右边出现了多条类型为“警告”的、来源为“TCP/IP”的日志, 其内容为:
TCP/IP 无法建立传出连接,因为选定的本地终结点最近用于连接到相同的远程终结点。 当以高速率打开和关闭传出连接时,会导致所有可用的本地端口被使用,并迫使 TCP/IP 重新使用本地端口进行传出连接,此时通常会产生这种错误。为了最大限度地降低数 据受到损坏的风险,在给定的本地终结点和给定的远程终结点之间的连续连接中, TCP/IP 标准需要等待一段最短的时间段。
我滴妈呀好长一段话,有点拗口,我们直接看核心内容:“会导致所有可用的本地端口被使用”,很明显了,当本地可用的端口都被占用的情况下,自然也就再也无法与外界进行TCP/IP连接了。若要问我怎么办?很好办,将本地可用端口数量设置到最大值,接下来便是操作时间。
打开CMD窗口,使用 netsh 命令修改可用端口数(注意各参数之间要有空格,且此命令比较长,务必注意从 netsh 开始到 num=63000 结束才是同一条命令,下面一共4条命令):
netsh int ipv4 set dynamicport tcp start=2000 num=63000
netsh int ipv4 set dynamicport udp start=2000 num=63000
netsh int ipv6 set dynamicport tcp start=2000 num=63000
netsh int ipv6 set dynamicport udp start=2000 num=63000
以上命令是将TCP和UDP协议的可用端口设置为启动端口2000,端口个数为63000,即:2000~65000 端口均为TCP/UDP协议的可用端口范围,给你这么多的端口就再也不怕没有端口用了。(这里注意:一般情况下大家没有启用ipv6的可以不用执行后面的2条命令,只需要执行前面2条与ipv4有关的命令即可)
接下来便是见证奇迹的时刻,命令成功执行完,于是打开浏览器,熟练地输入百度的网址,我滴妈呀!久违的度娘终于得以相见啊!竟然可以正常上网了,这效果杠杠的!!!不过保险起见,以防又出现之前昙花一现的场景,我又继续观察了一个星期,果然再也没有出现突然断网的情况了,看来此毛病已经得到了根治,于是特撰此文用以记录,希望在大家遇到类似的情况下可以帮助你们解决实际问题。对于一般情况的不能上网而言,上述的8个排查方法执行到第5个基本就能解决问题了,倘若是遇到了像我一样的情况,那就果断一干到底吧!大力出奇迹!