能在家学会的网络技术

 

前言

上大学的时候,为了能在宿舍电脑之间架个局域网打“红色警戒”,硬着头皮自己去买网卡、同轴电缆、集线器、双绞线。那个时候上网还很困难,网络知识的资料非常少。那个时候的网卡附带的说明书,上面记载了双绞线的排布方法,当时的我一直收藏着这只有一页的说明书,如获至宝。时隔多年,现在网上的资料非常多了,但是网络知识的入门教程,特别是可以立刻动手尝试一下的教程,还是不很多。所以我想从我自己的学习过程作为依据,整理一下整个知识体系,帮助后来者减少中间走的弯路。

很多介绍网络知识的书籍,一上来就会给出上面这个图,初学者一看就懵逼了,这里面的字眼,没一个是知道啥意思的。所以我希望通过大家日常使用的软件,来一一介绍,希望看完本文,最后再回过头看这个图,能理解这个图是啥意思。我会根据这个图,从上往下来介绍。

浏览器和网站

我们日常使用网络最常见的过程,就是打开一个浏览器,然后输入一个网址。我们可以通过稍微深入一点点的去观察这个过程,来学习一部分网络知识。

 

HTTPMIMEHTML

探索网页的打开过程

让我们用 Chrome 浏览器在电脑上打开一个网站,但在此之前,稍微做一点点准备。我们需要先打开浏览器的“开发者工具”:右上角三个点 → 更多工具 → 开发者工具。

打开“开发者工具”

在打开的窗口中,找到Network标签,需要注意看一下,左边是否有一个红色的圈圈里面有一个红色的正方形。这个状态表示“开发者工具”会记录从网络上首发的数据原文,也是我们得以探索网络知识的来源。

Network 标签页

现在在浏览器的地址栏输入这个地址:https://www.lua.org/,这是我在网上找的一个相对简单的页面,以便观察学习用。

浏览器页面显示内容
开发者工具显示内容

你应该能看到以上两个图的内容。一个是日常浏览器我们常见的显示内容;另外一个开发者工具中,会显示打开本次网站,网络上到底发生了什么事情的信息——浏览器从网站上下载了好几个文件:

  • www.lua.org:这是一个 HTML 的文档,包含了这个页面的文字内容和整体图文排版
  • lua30.gif:这是页面中左边蓝色写着“Lua”的那个图片
  • puc.jpg:页面右边灰色的写着“PUC”的图片
  • lua.css:一个控制页面字体等格式的文件
  • favicon.ico:出现在浏览器标签页左边的图标

在上面的表格里面,还记录了下载的耗时、下载的文件的大小。譬如www.lua.org这个页面,下载的大小就是 219 个字节,耗时 474 毫秒。现在我们知道了浏览器打开页面,是会下载几个文件的,但是具体是怎么下载的呢?我们可以进一步深入探索一下。

点击具体一个下载的文件

我们点击一下www.lua.org,可以看到右面出现了一个窗口,上面分为 Headers/Preview/Response 等分页。其中 Headers 分页,就包含了“如何下载文件”的信息,而这套下载文件的方法,有一个特别的名字,称为 HTTP (Hypertext Transfer Protocol),分页这里的 Headers 指的正是 HTTP 协议中的“头部信息”,这些信息详细描述了下载一个文件的方法。为了更清晰的看到这个过程,我们需要把Response HeadersRequest Headers旁边两个Raw的框框勾选上,查看最原始的网络报文。

当我们在浏览器的地址栏输入一个网址后,浏览器就会向网站服务器发出一个请求,请求的内容就是这里Request Headers所显示的内容。这些内容完全就是以文本形式(和你用记事本里面写的文字的格式一样),一行行的组织起来,发给服务器。

HTTP 请求 Header

需要注意的有以下两行:

  • GET / HTTP/1.1 这一行表示需要下载一个路径为 “/” 的文件。如果我们输入的地址是 www.lug.org/index.html,那么这里发送的请求将会是 GET /index.html HTTP/1.1
  • Host: www.lua.org 这一行表示我们请求的网站域名是 www.lua.org,这个是在地址栏输入来确定的。(由于一个网站服务器可以承担多个域名的请求,所以请求的具体哪个域名,是需要明确的在请求报文中写出来的)

对于服务器网站的返回,是比较复杂的。这种返回一般分为“头部”(Header)和“身体”(Body)两个部分,“头部”是纯文本的,一行行的发回来;“身体”则是跟具体下载的文件内容有关。现在我们请求的是一个网站页面,所以也是文本的。

HTTP 响应 Header

响应的 Header 表示了下载文件的情况、类型、大小:

  • HTTP/1.1 200 OK:这里的 200 被成为“响应码”,代表这次下载是否成功,200 这个数字就是成功的意思。另外一个广为人知的响应码是 404,表示你要下载的文件在服务器上找不到。(可能是网页文件被删除了,但是指向这个页面的链接还在)当然还有很多其他的响应码,譬如 500 表示服务器程序出错了,304 表示有缓存等等……
  • Content-Type: text/html:这个表示本次下载的文件内容的类型,浏览器是一个强大的软件,支持显示各种格式的文件,除了 html 格式网页以外,也支持多种图片、音乐、视频等等,如果服务器返回了一个浏览器不认识的格式,譬如 application/unknown 之类的,浏览器会提示用户是否要“下载这个文件”,让用户自己找其他程序去打开这个文件。当然我们这里的例子,是一个页面,text 是主类型,表示是文本文件,html 是子类型,表示是一个网页。
  • Content-Length: 2799:这个表示下载的文件的长度,2799 表示需要 2799 字节。由于网络下载是需要时间的,所以浏览器会一直等待,从网络上下载了 2799 字节的数据之后,才认为这个文件下载完成了,否则浏览器的地址栏会一直有一个“转圈”的图标表示正在下载。

除了上面提到的 Header 以外,其他的 Header 也各自有不同的功能,这些功能很多是不会被显示在网页内容上的,但也是非常重要的。

下面我们来看看响应的“身体”部分:

响应的 Body

这部分内容是一个文本文件,以 HTML 这种格式编写的网页。这些文本会确定网页要显示什么内容,里面也会包含其他网页的跳转链接,还有图片的链接等等。浏览器读取到图片的链接的时候,就会再次向服务器发起一次下载请求。因此我们才看到除了 www.lua.org 的下载记录以外,还有 lua30.gif 和 puc.jpg 的下载记录。我们可以看到下载图片的地址写的是 images/lua30.gifimages/puc.jpg。我们还可以看一下这两个文件的下载记录,可以看到和上述类似的过程。

下载图片的 Header

下载的图片也可以在开发者工具查看到:

下载文件的预览

从 Header 里面看到 GET /images/lua30.gif HTTP/1.1 里面的文件路径,和之前 HTML 中写的图片地址 <IMG SRC="images/lua30.gif ...>的文件路径一致。而响应的 Header 中,用image/gif来告诉浏览器,这个文件的主类型是 image,子类型是 gif。浏览器就根据这个类型信息来决定如何处理,在这里就是显示这个图片。决定浏览器如何显示文件的指令,并不是根据文件名的后缀 .gif,而是根据响应的 Content-Type 的 Header 的内容。根据响应 Header 中的 Content-Length: 187020,浏览器会下载后续的 187020 个字节的数据,作为 gif 格式图片的内容,然后显示这个图片。

对于 Content-Type 的内容,有一个专门的术语来代表:MIME(Multipurpose Internet Mail Extensions),意思是多用途互联网邮件扩展。这套描述数据内容格式的标准,同时也在电子邮件系统中使用,我们可以在电子邮件中插入各种格式的文件附件。

至此,我们大体的了解了 HTTP 协议的内容。总结一下,就是:

  1. 浏览器和网站服务器是通过一个请求,对应一个响应进行通信的。不同于 QQ、微信、网络游戏这类软件,它们可以同时进行数据的收、发,而无需请求后等待一个响应。
  2. 请求和响应都由一系列的文本文字,一行行的组成 Header 部分,用于指定要下载的文件,以及返回文件的类型、大小。Header 还被用于其他很多功能,譬如缓存控制、Cookies 跟踪等等。
  3. 响应的 Body 部分直接是下载文件的数据内容,很多时候并没有进行其他编码。最常见的是文本的 HTML 内容。

但是,我们还有一个问题没有提及,就是我们去请求的网站服务器,到底是一个什么东西?为什么输入一个域名,就可以联系到一个具体的网站服务器了呢?

这个问题下编介绍。这个问题下篇介绍,由此我们可以进入 TCP/IP 的世界。

从网页到 TCP/IP

本篇我们会探索以下知识:

 

URLDNS

认识“网址”

我们先来研究一下我们在浏览器输入栏填写的“网址”:

https://www.lua.org/

技术上来说,这串字符被称为 URL:统一资源定位符(Uniform Resource Locator)。
上面这个 URL,我们可以分为几段:

  1. https,这部分被字符 :// 与其他部分隔开。这部分叫做 Scheme,表示浏览器使用什么方法和服务器通信(也就是协议)。除了 https,浏览器支持的还有 http/ftp/mailto。
  2. www.lua.org,这部分被字符 / 与其他部分隔开。这部分叫做 Domain Name,中文称为“域名”,它代表了服务器的地址,浏览器通过这个地址去互联网上找到对应的服务器。这部分也是随后我们需要进一步探索的部分。
  3. / 后面的部分,虽然啥都没有,也是个一个部分。这部分称为 Path To File,就是要访问的文件路径。作为网站首页,一般不写的话,会默认为访问 /index.html,不过这个配置是网站服务器控制的。

我们做的第一个实验,是玩一下 URL:请把 mailto://2740168@qq.com 输入到 Chrome 浏览器的地址栏中,看看会发生什么?

弹出了让你打开邮件客户端,如果你有配置好一个电子邮件账号,就可以直接给 2740168@qq.com 发邮件了。以前好多网站,会把“联系我们”的链接,就写成这种 mailto://xxxx@xxxx.com 的形式,让用户点击之后直接给预设的邮箱地址发邮件。不过现在电子邮件已经很少人用了,所以现在比较少见这样的链接了。

URL 的定义除了我们上面说的三个部分,实际上还有更丰富的含义:

  • 域名部分,有些浏览器还支持直接在 URL 中填入用户名和密码,用来快速进入一个有账号控制的地址,类似:https://username:password@www.xxxxxx.com/
  • 端口 Port 部分(上图写的是 80),是服务器上一个特定的通信参数,这个数字范围 0-65535 的。这个参数控制了浏览器建立 TCP 连接的时候,使用的端口参数,这也是我们下一步要谈论到的一个知识:TCP 协议的通信地址。
  • 路径 Path to the file 部分,一般看起来好像一个文件路径,常用的 Web 服务器软件也会依次作为下载路径的一部分,在设置好的文件路径下开始寻找。如果找不到,就会返回常见的 404 页面。
  • Parameters 部分,也有叫 Query String 的,这个部分是以问号 ? 开头,用 = 号和 & 号组成的一组字符串。这个往往被一些 Web 应用程序用来作为“动态参数”输入,以前有些在网页上填写的输入框都是以这个方式传到服务上的。
  • Anchor锚部分,这个部分可以在长长的网页上定位一个位置,让浏览器快速的跳转到那个页面上,大家如果写 html 的话,就可以加入这种“锚点”的标签,让用户点一下跳过去。常见于网页的“回到开头”的链接上。

 

以上的部分,如果要做个实验来具体的体验,都是可以的,但是有点偏离本文的学习路径,咱们暂时跳过,如果有兴趣的读者可以给我留言,我后面贴一下这些实验的做法也可以。

URL 作为一种广泛应用的互联网资源描述方式,除了用于浏览器以外,很多别的软件也会用,譬如版本管理软件 SVN,我们就能看到类似这样的地址:svn://xxxx.xxxx.xxxx/path/

认识 IP 和 DNS

下面我们专注于“域名”部分。我们今天所使用的互联网,所使用的技术被称为“TCP/IP”网络,而每个网站的域名,都必须要至少对应上 TCP/IP 网络上的一个通信地址。这种通信地址,被称为“IP 地址”(Internet Protocol Address)。我们可以通过一个小工具来看看,刚刚访问的网站,它的 IP 地址是啥。

首先,我们需要调出一个命令行窗口 cmd.exe,我们可以在 windows 下按快捷键 Win+S,打开”开始菜单”的搜索栏,输入 cmd.exe,并且启动这个程序。

然后我们可以在那个黑黑的窗口中输入我们的命令行工具,来探索网络了。首先,我们输入命令:ping www.lua.org,把上面浏览器实验中的网站域名 www.lua.org 作为 ping 命令的参数输入进去,然后按回车。

ping 这个工具,是用来检测 TCP/IP 网络上,某个特定服务器是否能访问的一个小工具。当我们输入了域名或者 IP 地址作为参数,这个工具就会尝试向所指定的互联网地址服务器,发出一些网络数据包。如果目标服务器支持 ping 功能的响应,会原封不动返回 ping 工具发来的数据包,这个时候 ping 软件就能统计这一来一回的时间,并且打印出来。这样我们就能直到,访问目标服务器的延迟时间大概是多少了。上面的例子中,延迟是 162 毫秒(网速还行)。

我们可以发现,在输出的文字中,出现了一串特别的字符:46.175.8.47,这就是 IP 地址。那么,ping 这个软件,是如何知道 www.lua.org 这个域名要转换成 46.175.8.47 这个 IP 地址的呢?——这是通过操作系统(windows)来实现的:操作系统会把 www.lua.org 这个字符串,发到配置好的某个互联网服务器上,查询到对应的 IP 地址。这个过程称为“域名解析”,而提供这个解析的服务,称为 DNS (Domain Name System)。

我们可以通过一些方法,来看一下,我们的 DNS 服务器的 IP 地址是什么。我们找到 windows 的设置面板,然后找到“网络和 Internet”,在“状态”这一栏,找到你上网功能的“属性”部分。

在窗口中一直往下滚动,你就可以看到 DNS 的部分了。

这里显示的 DNS 服务器是: 10.93.128.1 这个地址。实际上,你也可以自己手动去设置不同的 DNS 地址,现在网上也有很多“公益”“开源”的 DNS 服务供大家免费使用,譬如:8.8.8.8,或者中国电信位于广州的 DNS 服务:202.96.128.86。手工设置的截图我也贴一下,不过,如果大家能正常上网玩耍,一般不需要手工修改这个配置。

 

现在我们上网的路由器一般都提供了自动配置这个参数的功能,避免用户自己去填这个地址填错,导致无法正常上网。

我不厌其烦的贴出上面的截图。是因为后续我们可能需要频繁的打开 windows 操作系统的“网络设置”界面,来做一些有意思的测试。所以先热身一下。

手搓一个 Web 服务器

现在我们知道网站域名实际上会被转换成一个 IP 地址,而浏览器本身也是支持直接输入 IP 地址进行访问的,所以我们可以尝试自己做一个简单的 web 服务器,来验证一下上面我们的 HTTP 知识是否正确。

网络服务器除了需要有一个 IP 地址以外,还需要一个程序,使用所谓 TCP(Transmission Control Protocol)协议,来提供网络服务。TCP 协议的能力,我们的 windows 操作系统已经具备了,程序员可以写个程序来使用这个能力。所以我们在开始之前,也需要一个工具,来帮我们做个简单的 TCP 服务。至于什么是 TCP 协议,我们可以在实验中慢慢体会,现在先下载这个叫 NetAssist 的软件,可以从下面的网盘下载,或者网上搜索一下(注意别下载到木马软件了)。

 

链接:https://pan.baidu.com/s/15m-dzhuRVM3K9qlob8JmEw?pwd=tzmc

这个软件不需要安装,直接双击就可以运行了。然后在软件左上角的“网络设置”中如下填写:

  1. 协议类型:TCP Server
  2. 本地主机地址:127.0.0.1
  3. 本地主机端口:8899

然后点击下面的按钮“打开”。点击之后,可能 windows 会弹出一个你见过的提示窗口,说是有程序要获得什么网络权限之类的,你的“允许”就好了。

 

以前你可能不知道,为啥有的程序运行的时候会弹出这个窗口,现在可以告诉你,如果有个程序试图启动一个网络服务,也就是监听某个网络端口,windows 出于安全考虑,会用这种方式告诉你。

至此,你就已经启动了一个网络服务。这个网络服务程序就是 NetAssist 这个软件,它使用了 windows 操作系统的网络功能,在 IP 地址 127.0.0.1 上,监听了 8899 端口。

这里的 IP 地址 127.0.0.1 是一个特殊的网络地址,你就算没上网,这个地址也是可以用,而且不需要你配置的,这个地址就是表示当前本地主机,也就是中文的“自己”,或者英文的“me”的意思。你可能发现还可以选择 0.0.0.0 或者另外的一些 IP 地址,这些我们后面会提到都是些啥,现在我们可以先简单的用 127.0.0.1 这个地址。

这里的 8899 端口,是操作系统为了让一台电脑上,多个程序都能使用网络,而编出来的一个号码。任何程序,在使用 TCP/IP 网络功能的时候,都要向操作系统申请一个这样的号码,称为“端口号”。一旦申请成功后,操作系统会检查收到的每个 TCP/IP 协议网络包,通过端口号来确定,把这个网络信息包发给申请的程序。一个程序可以申请一个端口号,也可以申请多个;但一般情况下,不可以多个程序共用一个端口号。端口号的可用范围为 0-65535 我们这里填写的 8899,因为这个数字没其他程序使用,所以操作系统很爽快的让我们申请成功了。——因此 NetAssist 程序,就可以在 127.0.0.1 这个 IP 上,监听所有发往 8899 端口的 TCP 数据了。

下面,我们来准备一段文本数据,作为我们的手搓 WEB 服务器的返回内容。内容就是上面我们分析的 HTTP 协议的报文:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 59

<body>hello <a href=“http://www.gcores.com/”>fun</a></body>

这个报文构造了一个简单的网页,上面显示了hello fun这样一行字,并且fun这个词还是个链接,点击会跳去一个有意思的网站。注意这个上面的 Content-Length: 59 是经过计算的,刚好是下面网页内容的长度,如果你修改了下面网页的内容,需要数一下多少个字符,然后修改这个59为你真正的内容长度。

接下来,我们打开一个浏览器,譬如 Chrome,在地址栏上输入:http://127.0.0.1:8899,然后你会看到浏览器并没返回什么内容,标签页有个转圈的动画,好像正在载入的样子。这个时候,请麻利的拷贝上面我们准备的那段 HTTP 报文,然后麻利的切换到 NetAssist 软件,在右下角“数据发送”窗口,把内容粘贴过去,然后点“发送”。

此时,你就会看到浏览器窗口中,出现了一行字 hello fun[1],至此,我们手搓的 Web 服务器实验成功了。你可以在 NetAssist 的窗口中,看到之前我们讨论的 HTTP 请求报文(Headers)。

我们这里使用了 IP+Port 的方式填写 URL 地址,浏览器也是支持。一般情况下,很多网站并不需要填写 Port 端口数据,如果你不填写,在地址以 http 作为 scheme 的情况下,浏览器默认会访问 80 这个端口,如果是 https 作为 scheme,浏览器则会访问 443 端口。至于 https 和 http 的差别,也是一个很有意思的知识,以后有机会聊。

总之,我们现在知道了,所谓网页浏览,基本的过程就是:

  1. 有一个软件程序,在连接了 TCP/IP 网络的电脑上运行,监听了某个 IP 和 某个端口
  2. 另外一个软件,通过网络,和上面这个软件所运行的 IP 和端口,建立了一个“连接”
  3. 发起连接请求的软件(称为客户端,一般是浏览器),向“网络连接”发送了一堆 HTTP 的请求报文信息。
  4. 接收到请求的软件(称为服务器端,著名的有 IIS、nginx、apache 等),查看了客户端发来的信息,然后把对应的数据,以 HTTP 响应报文的方式,回写到当前的“网络连接”里面。

我们上面提到的,HTTP 协议里面的各种 Header 所对应的功能,都是客户端和服务器端,互相之间通过建立的 TCP/IP 连接,进行数据传输行为的一些约定。譬如客户端会要求 GET 某个路径(PATH)的文件,服务器就通过传过来的 GET 的文件路径信息,在服务器磁盘的某个地方查找这个文件,然后把文件内容发给客户端。而我们手搓的服务器,不管你要求什么路径的文件,都是返回同样的内容,大家可以尝试修改浏览器的地址栏信息,加上一些如 http://127.0.0.1:8899/aaa/bbb.html 这样的内容进行测试,返回的还是同样的页面内容。

至此,我们大体的体会了一下 TCP/IP 网络功能,和网页功能之间的关系。但是 TCP/IP 并不仅仅可以用于网页浏览服务,我们玩的网络游戏、微信等等很多网络功能,都是使用 TCP/IP 功能的。这些都是通过一些应用程序,使用操作系统的 TCP/IP 功能来实现的。

在刚刚的例子当中,有一个重要的问题没有被讨论:为什么我们知道了 IP 地址,就可以把数据通过网络发到对应的电脑上?所以我们下一篇,通过操作系统的 TCP/IP 设置,来看看它具体是如何运作的。

探索“路由”

本篇我们将会学习以下概念:

 

IP 地址、子网掩码、网关

以前,“路由器”是和“交换机”“集线器”“网桥”等等名词,共同存在于”网络技术”这个不为人知的世界中的。当初为了搞明白这些词是啥意思,可是非常不容易的。然而,现在“路由器”已经成为京东、淘宝上的一个常见搜索的产品名字了。可是,你知道为啥那个屁股上插了几根线的玩意儿,叫“路由器”而不是其他什么名字吗?跟着下面的步骤操作一下,你就知道啥叫做“路由”了。

根据前面的文章可以知道,在互联网上每个电脑(或者设备),都需要有一个 IP 地址(实际上你可以拥有多个 IP 地址,只要对应的网卡能用的上);有了这个 IP 地址,才能通过互联网互相通信。所以,我们可以用以下命令显示当前的 windows 电脑的 IP 地址信息——使用 cmd.exe 打开命令行窗口,输入指令:

ipconfig

然后你可能会得到一堆字符输出,其中会有一些类似如下图的显示:

这里面显示了本电脑的 IP 地址为 192.168.1.27,这里显示的 IPv4 和 IPv6 是 IP 地址的两个不同的版本,暂时我们可以只看 IPv4。除了 IP 地址以外,还有两个奇怪的参数:子网掩码、默认网关。——我们马上可以做一个实验,来动手研究他们的含义。

我们现在输入命令行:

ping 192.168.1.1

上面的 192.168.1.1 你可以根据你电脑的实际情况,改成上面你所看到“默认网关”的具体 IP 地址。

我们可以看到有一些输出,表示 IP 为 192.168.1.1(或者是你的默认网关的 IP)的电脑,给本电脑的 ping 返回了数据。(这些数据每个占 32 字节,一共发了 4 个数据包)这表示本电脑 192.168.1.27 到 192.168.1.1 是能连通的。这个工具之前我们测试 www.lua.org 网站服务器的时候,也以类似的方法用过。这个默认网关一般来说,就是你家里面的路由器的 IP 地址,那个小小的盒子,也可以算是一台联网的电脑,具有自己的 IP 地址。

 

以前老式的 ADSL 拨号上网情况下,我们并没有一个自带 IP 的路由器,而是通过一个 Modem 调制解调器连接互联网,那个情况下,默认网关 IP 指向的则是存放于电信运营商提供的一个设备。

然后我们来修改一下自己的 IP 地址,为了避免不同 windows 版本的 GUI 界面的差异。我使用命令行进行修改,请以管理员身份重新打开 cmd.exe 窗口:

然后输入以下命令。注意输入之后可能会让你的电脑断网,所以最好保留一下上面你看到的 IP 地址的内容,完成实验后重新设置回来。

netsh interface ip set address "以太网" source=static addr=192.168.2.27 mask=255.255.255.0 gateway=192.168.1.1

这个命令,其中 “以太网” 这个字符,是对应之前 IP 地址输出窗口中的“适配器”部分的(也就是你的网卡在 windows 上配置的名字,现在电脑往往会有两个以上的网卡,包括 WiFi 网卡和有线网卡,还有的会有蓝牙网卡),如果你的适配器叫其他名字,请修改成对应的名字。

addr=192.168.2.27 中,是把原来的 192.168.1.27 的第三段数字改成不是 1 的。并且注意 mask 一定要是 255.255.255.0 这个数值。这个命令的含义,就是把“以太网”这个网卡(或者叫“网络适配器”)的 IP 地址配置成 192.168.2.27,并且子网掩码参数改成 255.255.255.0。

当你执行完上面这个命令,你应该会发现:电脑断网了!。断网了咱也先不要着急,我们还得继续实验,在命令行窗口中继续输入以下命令:

ping 192.168.1.1

你会看到以下返回,表示刚才还能连通的网关服务器,现在已经连不通了!

等下我们再解释,为啥改了一下 IP 地址就连不通原来还能连上的电脑。现在我们先尝试恢复网络,可以在同一个命令窗口运行命令:

netsh interface ip set address "以太网" source=dhcp

上面这个命令的作用,就是把 IP 地址从手工设置,改成自动获取。如果你的电脑运行这行代码后还是不能上网,可以参考上面改 IP 的命令,把 IP 地址的第三段改为原来的值,并且修改 mask 参数为原来子网掩码的值,以及修改 gateway 参数为原来的“默认网关”的值。

下面我们来解释一下,为什么改了 IP 地址的其中一段,就会导致原来能联通的网络,变得连不通呢?首先,我们需要了解一下 IP 地址的组成:IPv4 地址一般看起来是由四个数字,通过三个小数点连接起来的。实际上,IPv4 的地址只是一个 32 位二进制长度(bit)的整数,其十进制的取值范围是 0~4294967295。互联网上的所有设备(手机、电脑、游戏机等等)都是用的一个数字编号,来代表自己的地址。我们写成 xxx.xxx.xxx.xxx 的形式,基本是为了避免太长的一个数字给记错了而已。

我们知道在现实世界中,如果我们要向一个地址写一封信,或者发一个快递,一般都是需要写省、市、区、街道、门牌。具体发送快递的时候,物流公司把需要把目标地址,分成不同的一段段空间,先找空间,再找逐步细化空间,最后发到具体的地址上。但如果好像互联网上的设备,如果只有一个数字作为具体地址,就算这个地址不会重复,那又如何才能一步步的找到最后的目标呢?

答案就藏在 IP 地址的另外两个参数里:子网掩码(netmask)、默认网关(gateway)。

当我们要发送一个数据包到另外一个 IP 地址的机器上(譬如上面实验中的 ping 命令),我们是知道自己的 IP 地址,以及目标的 IP 地址的。操作系统会根据子网掩码,来判断是否目标 IP 地址的机器,是否是和当前电脑在同一个“子网”中。

  • 如果是在同一个子网中,就会让底层网卡尝试直接连通目标机器,在常见的“以太网”(所谓局域网)中,这个尝试可能是一种数据广播,也可能是通过专用网络设备“交换机”来转发数据。
  • 如果操作系统认为目标地址不是和自己在一个子网中,就会把数据发给配置中的“默认网关”的机器,请它帮忙转发这个数据。

在上面的实验中,我有意让目标 IP 和本机的 IP 地址处于不同的“子网”中,而且默认网关也不起做(因为不在同一个子网中),所以 ping 的结果就是超时,表示无法连通。

那么,操作系统是如何判断,一个目标地址是否和本机处于同一个“子网”中的呢?这个时候就需要“子网掩码”的功能了。在我们的实验中,子网掩码是 255.255.255.0,如果把这个地址,以 IP 地址的方式改成二进制,就会是 11111111 11111111 11111111 00000000 这样一个数字,然后我们用这个子网掩码的二进制数对 IP 地址的二进制数,进行“与”运算,就能得到“子网网段”的地址值。这里的“与”运算,其实就是对应位掩码是 1 的,就保留下来;是 0 的,就变成 0。

子网掩码并不一定需要是 255 和 0 作为组成部分的,它可以是任何数字。只要拿这个数字和 IP地址按二进制位进行“与”运算,就能得到子网的网络地址。根据上面的实验,我们可以知道发起数据的电脑和接收数据的电脑的 IP 地址,经过计算各自的子网地址是:

  • 发起方 IP 192.168.2.27,经过 255.255.255.0 计算后,结果是 192.168.2.0
  • 接收方 IP 192.168.1.1,经过 255.255.255.0 计算后,结果是 192.168.1.0

上面这两个子网地址并不一致,所以操作系统判断:本机和目标机器不处于同一个子网内,需要通过网关转发数据。而网关刚好也配置的是 192.168.1.1 这个不在同一个子网内的机器,所以数据只能是没有回应。一旦我们把本机的地址,改成了让操作系统认为,是和目标机器同一个机器的子网内,我们就又能 ping 通了。

我们既然知道了,在同一个子网内,数据是根据子网掩码来判断和传输的,那么不在同一个子网内的数据,又是如何传递的呢?其实过程是一样的,只是不在一个子网内的数据,会先发给同一个子网内的“默认网关”,这个网关设备负责转发到另外一个子网去(也就是上级网络)。“网关”提供的这种服务,称为“路由”服务。这个过程有点像我们送快递:

  • 先判断收件人和发件人是不是在同一条街道的(通过判断子网地址),如果是的话,快递小哥就直接给你送过去。
  • 如果不是一条街道的,快递小哥会把包裹带到自己的快递站(默认网关),然后由那里的工作人员,根据地址上写的“区”地址,来决定要发给哪个快递站(某个子网的网关)。
  • 如果一个快递站(网关)发现收到了一个从其他街道发来的包裹,而且地址是本街道的(子网地址一致),就会想办法派人送上门。

为了直观的展现这个过程,我们还是可以用命令行工具进行测试:

tracert -dR -4 www.baidu.com

tracert这个软件,就是记录和显示数据包如何到达目的 IP 的一个工具。从输出我们看到,目标 www.baidu.com 的 IP 是 183.2.172.185,经过了 15 次转发,最终到达了这个 IP 地址。而第一次转发,经过的正是默认网关 192.168.1.1,而第二次转发的网关地址 100.69.0.1,这个 IP 地址通常是路由器的 WAN 的网关,也就是“更上一级”子网网关的地址。后面经过的每一条记录,都可以理解为经过一个“快递站”(网关)的地址。

上图是我的路由器管理界面,上面记录 WAN 的地址,可以看到都是以 100.69. 开头,很可能其子网掩码是 255.255.0.0,从而和 100.69.0.1 处于同一个子网(计算得到子网地址都是 100.69.0.0)

每个网关之间的数据转发规则,往往不是好像我们家里的路由器那么简单:不是一个子网的,全部发给上级网关——而是有一个“路由表”来决定数据包的转发规则的——这方面有很多细节,是一个专门的课题。但我们现在,只需要知道,全世界的所有设备,就是通过这样一次次的转发,最终连接到一起的。

本篇文字的末尾,我们接触到了新的概念: WAN,下一篇,我们会从路由器的配置着手,开始了解更多互联网的知识。

了解路由器

上面所做的实验,我们用的都是 IPv4 的地址。这个 v4 表示的是,用 4 个字节来表示一个地址。4 个字节能表达的最大十进制数,大概是 42 亿多,而今天,全球互联网的使用者已经超过 40 亿了,更别提现在一个人可能有几个设备接入互联网(手机、ipad、笔记本),以及现在成千上万的网络服务器。这些庞大的互联网设备,都需要 IP 地址,所以 IPv4 地址不够用的问题越来越严重。在互联网诞生的那个年代,网络带宽和设备容量及其有限,导致了地址设计时,觉得 4 个字节已经足够了,同样的问题,在使用 2 位十进制数表示 19xx 年也出现过,酿成了著名的“千年虫”事件。

为了解决 IPv4 不够的问题,一个最常见的方法,就是 NAT 技术。如果我们在家上网,我们通过手机的网络设置,或者电脑的 ipconfig 命令,查看我们设备的 IP 地址,往往看到的都是以 192.168. 开头的样子。别人家手机和电脑的 IP 还是 191.168.x.x 的样子。如果没有特别的方法,接入互联网的 IP 地址重复了的话,信息是如何能做到正确的流动呢?

拥有两个地址的设备

我们看到的以 192.168.x.x 为形式的地址,其实是一组特殊的 IP 地址。这类地址叫做“局域网 IP 地址”,也有叫“内网地址”的。互联网的 IP 地址,是由一个叫“互联网名称与数字地址分配机构” (ICANN) 的全球化组织负责的,它在全球范围内协调此类唯一标识符,如果没有这种协调,我们就不会拥有统一的全球互联网。而 192.168.x.x 这组地址,是不会被分配给任何实际需要直接接入互联网的设备(或者人)的,这些地址是保留给大家在“内部使用”的,比如一个公司内部、一个学校内部、或者一个家庭内部。这样所有的设备和程序,就能很快的发现,如果有信息是使用这种地址的,就不需要麻烦的往互联网上传了。实际上,被保留作为“内网地址”的 IP 段,还有另外两段:

  1. 10.x.x.x:以 10 开头的所有地址
  2. 172.16.0.0 – 172.31.255.255 这个范围的地址

如果我们在家上网,当我们发送一个信息到内网地址的数据,不管是不是在同一个“子网”的,我们的互联网网关(路由器),都不会发到互联网上去。类似的,另外一个特殊的 IP 127.0.0.1,表示“本机”,发往这个地址的信息,甚至不会被操作系统发到网卡上,只会在当前电脑上处理。以前我们监测网卡是否安装好的时候,会用 ping 127.0.0.1 来判断。

前文有提到,我们的路由器的 IP,就是我们电脑上的“默认网关”,而路由器一个最重要的功能,就是当我们的电脑,需要发送信息到互联网上的时候,帮我们把信息转发出去。这种转发的信息,会分成一个个的数据包(又叫数据分组)。在我们所谓的 TCP/IP 数据包里面,会包含发送者的 IP 和端口号,以及接收者的 IP 和端口号。路由器帮我们转发数据的时候,就会把“发送者 IP、端口”部分的信息,从内网地址,改成路由器自己的“公网地址、端口”(不属于内网的地址就是公网地址啦)发送出去。我们可以通过某些网站,来看一下这个过程:这个网站会在页面上,显示 HTTP 请求,也就是发送的 TCP/IP 数据包的发送者 IP。

访问地址 https://ip.900cha.com/ 你可以看到:

这个上面的地址,就是你访问其他网站的 IP 地址了。

在路由器管理界面上,标注的 LAN(Local Area Netword),指的就是我们的手机、电脑这些使用“内网 IP”的设备,所组成的网络;而 WAN(Wide Area Network) 指的是,路由器通过电信运营商接入了的互联网的网络。路由器就好像一个插了两个网卡(现在好多电脑都做在主板上,不需要插卡了)的电脑,一边连接着互联网,使用者公网 IP;另外一边连接着家里的网络,使用内网 IP。每个从我们的手机、电脑发出的数据,都通过路由器改写地址之后,发到互联网上。这样的一个把内网数据发到外网的过程,就是所谓 NAT(Network Address Translation) 服务的内容。

本来我想整一下端口转发的实验,但是现在电信的用户早就没有自己的真正公网 IP 了,100.64.x.x 的 IP 属于是运营商的内网 IP,运营商自己也搞了个 NAT,所以我们在路由器上看的 WAN 的 IP 其实并不能真正的被外界访问。这一切,都是因为 IPv4 早就不够用有引起,幸好,我们还有更好的选择,那就是 IPv6!

IPv6 降临!

IPv6 的地址长度是 128 位,而 IPv4 只有 32 位。所以 IPv6 可以给地球每个沙子一个地址。他的样子在之前我们的 ipconfig 指令中大家可能见过了。我的电脑的地址如下:

240e:3bb:ab3:6ee0:9c7d:2826:6be9:318c

这里的每个冒号之间,是一个 16 位数字,也就是 0-65535,也就是说两段地址,就等于原来的一个 IPv4 地址了,而 IPv6 一共有 8 段!

对于 IPv6 来说,不再需要“子网掩码”了,因为地址足够多,直接用前半段(240e:3bb:ab3:6ee0)表示网络号,用后半段(9c7d:2826:6be9:318c)表示主机号。由于这个数字足够大,网络号和主机号,各自都有 18446744073709551616(184亿亿)个号码,这也是足够够的了。IPv4 那些什么 ABC 类子网统统见鬼去吧!

由于地址足够多了,所以也不需要规定什么公网和内外地址了,直接每个上网的设备发 1 万个都够!所以也不需要搞什么路由器的端口转发,DMZ 配置之类的玩意。

下面我们用之前的手搓服务器,放在真正的互联网上吧!

  1. 第一步肯定是要拿到我们的 IPv6 地址,用 ipconfig 就能看到
  2. 我们启动一下 NetAssit,让他监听我们的 IPv6 的地址和 8888 端口,注意要选择“TCP Server IPv6”,地址选最后一个全是 0 的就好了:0:0:0:0:0:0:0:0,表示监听所有的地址。
  3. 用微信或者别的什么东西,把下面这个链接发到你的手机上。注意浏览器访问 IPv6 需要用中括号抱起来。
http://[240e:3bb:ab3:6ee0:9c7d:2826:6be9:318c]:8888/
  1. 把手机的 wifi 关掉,直接用 4g,以确保我们是通过互联网访问的自己的电脑。然后把上面的地址复制、粘贴到手机浏览器的地址栏中,点访问。这个时候,你的电脑的 NetAssit 应该可以看到一串字符输入,表示手机发的数据已经达到了。

  2. 把我们上面的那段 HTTP 报文填入到 NetAssit 的数据发送窗口,然后点“发送”按钮,手机上就能显示出页面来了!

 

好像用了 IPv6 之后,上面学的好多知识都没用了,譬如折腾个半死的 NAT 设置?其实并不要紧,因为网络协议是为了解决问题而存在的。计算机科学中,存在着所谓“一力降十会”“力大砖飞”的事情,就是因为硬件的速度、容量增强之后,很多问题都能迎刃而解。有价值的是,在有限资源的情况下,解决这些问题的思路。

希望以后所有的游戏,都支持用 IPv6 来通信吧!这样我们想联机,就再也不用去折腾什么路由器了!

自己夹网线不?

终于到了我最喜欢的做手工环节了🐷,想当年不提好汉勇,上班第一天做的事情就是:组装电脑(从一堆板卡开始)以及夹网线。不过,2402 年了,大家都是无线网络 WIFI 接入了,谁还夹网线呐?

WIFI 作为接入网络的硬件方式,我们最常见的就是“无线网络名字”和“密码”,如果想要蹭别人的无线网络,就得猜到密码。不过,这个“无线网络名字”和“密码”只是用来防止蹭网的吗?我们还有其他更好的防止蹭网的方式吗?下面介绍以下知识:

 

WIFI 设置和 MAC 地址

想要防止别人蹭网,最根本的方法就是设置 MAC 地址白名单功能。MAC 的意思是 Media Access Control Address 的意思,也叫物理地址。每个网卡都有一个固定的 MAC 地址,虽然很多网卡现在已经集成到电脑、手机里,你看不见一个“卡”,但是它还是存在的,所以每个能接入 wifi 的设备,肯定有一个无线网卡,同时也会有一个 MAC 地址。这个地址是由生产公司通过全球 IEEE 组织分配得到,然后写在网卡硬件上的,可以说是全球唯一的一个网卡身份证号。

在 wifi 网络这层,并不知道 IP 地址这类东西,它们只知道 MAC 地址,并且对这个地址进行信号传输。Mac 地址长度是 48 位(6个字节),比 IPv4 多 2 个字节,也就是可以多 6 万多倍。不过一般来说 Mac 地址冲突的概率很少,因为两个相同地址的网卡,正好出现在一个局域网里面的可能性非常的小。MAC 地址只用于同一个交换机内部,或者同一个 wifi 网络,这类小范围的网络之间的通信。如果要发数据去更远的地方,一般都会把数据发到路由器上,让路由器去通过更上层的 IP 地址去定位发送了。所以 MAC 地址比较像一栋宿舍楼里面,对于每个房间的“自编号”,它并不关心在邮政系统里面的地址位置,因为宿舍都有传达室,传达室大爷(交换机)知道这些“自编号”对应的房间就可以了。从这个角度看,MAC 的思想其实和 IPv4 的局域网 IP 加上 NAT 功能挺类似的。

所以我们可以在 WIFI 路由器(现在用的应该叫 Wifi AP 能力,AccessPoint)上去配置,只允许已经登记的 Mac 的设备接入我的 Wifi。

WINDOWS 上可以通过“设置-网络-属性”看到自己的 MAC 地址,然后填到配置表里面去。

 

ARP、以太网,以及混杂模式

现在,我们思考一个问题:我们可以给电脑和手机等设备,都设置 IP 地址(也有用 DHCP 自动获取 IP 地址的),但是,网络上的设备,是如何互相通知对方自己的 IP 地址的呢?特别是,如果在一个局域网中,你如果设置了一个 IP 地址,和另外一个地址冲突了,操作系统会立刻提示。这个过程是怎样发生的呢?

这里我们就需要了解一下 ARP(Address Resolution Protocol) 这个功能了。这个功能就是在一个局域网中,设置和管理 IP 地址的协议。windows 也带了一个同名叫 arp 的命令行工具。我们可以用 cmd.exe 运行一下这个工具看看:

arp -a

他返回了一个列表,里面对应的 IP 地址和 MAC 地址:

里面出现了路由器的 IP 192.168.1.1 以及其他一些 IP,这些都是记录在这台电脑上的 IP 对应 MAC 的列表。当我们 ping 过另外一个 IP 192.168.1.27 (我的另外一台电脑)之后,我们可以看到 arp 的列表里面就有了 192.168.1.27 相关新的信息:

说明在我们发起 TCP/IP 请求的时候,MAC 和 IP 的对应关系,自动的以一种机制被建立起来了,有了这种关系,我们的数据包才能真正的从一台硬件电脑传输到另外一个硬件电脑。但是这一切又是如何发生的呢?

我们用的局域网,现在被称为“以太网” Ethernet,这个网络技术,是 Xerox公司创建的,别看它是个打印机公司,它可牛逼了,GUI 图形用户界面也是它们家发明的。以太网的工作原理是:CSMA/CD 载波侦听多路访问/碰撞检测。这段字看起来很复杂,但实际上道理非常简单,我举个现实的例子来模拟一下这个过程。假设有几个盲人,坐着一个房间里面需要沟通。由于到底有几个人不知道,要讨论什么也不知道,为了避免大家一起说话听不清楚,于是他们约好了一套说话的规矩:

  1. 任何人说话之前,要先听一下有没有人在说话。如果有人在说话了,就闭嘴随机等一段时间再说。
  2. 任何人说话的时候,也要听着有没有人说话,因为有可能另外一个人走神了,和你一起开始说话了。如果发生这种情况,也闭嘴随机等一段时间再重新说刚刚那句话。
  3. 以上情况都没有,就一个人把话说完。

上面这个过程,其实非常简答,也是以太网的工作原理。如果发生了上面的情况1和2,就叫做产生了“冲突”,集线器会专门有一个叫 COL 的指示灯,一旦发生这种情况,就会亮一下。

对于我们常见的双绞线局域网(以前还有同轴线的)来说,如果使用最基本的集线器设备(看起来和交换机一模一样),你可以大概认为,所有的设备,都是被串联到一起的一组装饰灯。

当然,现在的交换机,内部有一些软件,可以减少上面的这种冲突,所以会比集线器贵一点,而且网络的带宽也好很多。

如果有一个设备发送数据,所有的设备都会收到,就好想开关一打开,所有的灯都点亮了一样。数据的 0 和 1,就是在网线上电压的低和高。因此以太网的所有数据都是广播的。而我们从 A 设备发到 B 设备的数据,只不过在发送的内容里面,也带上了 B 的 MAC 地址。就好像我们在房间里说话,会带上:那个谁XXXX,你听好了……。其他设备收到了不是发给自己的数据,就会不予处理。因此,如果要在局域网里面,问一下 IP 地址到 MAC 的关系,只要发一个广播,有设备应对就好了,同样,如果 IP 地址有冲突,也就是一个 IP 有两个 MAC 地址的设备发广播自己是,就会大家都知道了。

因此也有一种黑客的方法(或者叫安全漏洞),叫做 ARP 欺诈:只要有办法物理接入了局域网,我就可以先想办法把原来 IP 的设备弄挂掉,然后自己通过 ARP 协议广播自己的 MAC 代表原来的 IP。对于默认网关的攻击,是最有价值的,马上整个局域网想要往外发送消息,都会先发给这儿黑客的设备!这样黑客就能篡改和伪造各种请求。这么开来,如果蹭WIFI的用户,他们的设备有 ARP 攻击木马,还是挺危险的;同样,蹭别人 WIFI 的用户,可能那个网的网关,也是一个窃取信息的设备哦。很多 WIFI 不设密码,搞不好就是引诱你去用呢!一句话,不要蹭网,不要被蹭。

既然是广播,所以局域网里的任何一个设备,也是可以收到所有其他设备的进、出网卡的数据。我们的网卡,都有一个叫做“混杂模式”,设置为这个模式后,不管网络上的数据包接收地址是不是自己的,它都会收进来。以前一些网络管理和抓包软件就会利用这个功能,同样,如果你的电脑中了木马,十有八九也会把网卡设置为混杂模式,试图窃取同一个局域网的其他设备的数据。因此网吧为什么很容易丢账号,因为有很多人在网吧下载使用外挂。很多外挂本身就是一个木马类的泄密软件。一句话,不要用外挂。

 

至于混杂模式抓包,由于需要下载安装一些软件,然后还要和电脑的安全系统斗争一下,所以就不放在这个文章里面了,如果有兴趣留言给我,看是否专门开一篇。

对于有线网络来说,现在最常见的就是双绞线。之所以要一对对线绞在一起,是因为防止干扰,绞的越密,抗干扰能力越强,当然材料就用的越多。这就是所谓 3 类线、5 类线、超 5 类的差别。

这个抗干扰的原理也很简单:我们知道干扰的原因,是因为电磁场的变动,会导致铜线里面产生电流,这个电流和原先要传输信号的电流重叠,就会造成错误。而这种干扰,有一部分还是网络信号自己造成的:一根线上的电流,造成了磁场,这个磁场又产生了干扰电流。知道了原因,对抗的手段也可以设计了:

  • 让收、发数据两根线绞在一起,互相抵消产生的电磁场。
  • 让多根没有数据的双绞线,形成一个电磁屏蔽网络,减少外界的电磁干扰。

 

具体抗干扰还有很多细节,入门文章就不详细说了。

总结

网络数据的真实样子

所谓网络技术,就是围绕着一系列网络协议建立起来的软件功能。而所谓网络协议,则是指导网络上不同的软件应该如何工作的一套方法。如果有的软件不遵守这套方法,网络上与之通信的其他软件有可能就没法正常工作了。

为了让大量不同功能的软件,能工作在大量不同的底层硬件网络上,人们把网络数据包一层层的添加上额外的内容,这样每一个不同的功能模块,都能根据对应的网络数据部分执行自己的能力。这也就是所谓“协议栈”:不同的功能一层层叠加起来,在一个数据包中完全体现。

互联网的协议栈,现在分担这些不同部分的功能的软件基本已经确定:

  1. 网卡驱动程序负责“数据链路”和“物理”的功能,譬如双绞线网络和 WIFI 网络的实现
  2. 操作系统的 TCP/IP 模块,负责逻辑意义上的“主机”之间的互联和传输,可以通过操作不同硬件网卡的驱动程序,实现不同物理网络之间的数据互通。并且提供程序接口给开发者使用网络能力
  3. 应用程序通过调用操作系统的网络 API,一般叫做 socket 库(袜子库,哈哈),来实现各种具体的网络功能。常见的应用程序可以使用的“袜子”有两种,一种叫 TCP,另外一种叫 UDP。基于这些库,应用程序之间又协商出诸如 HTTP、POP(邮件)、SSH(加密登录)等“应用层”协议。游戏服务器和客户端之间,也会使用 TCP 或者 UDP 进行通信,设计这类协议就是我最常见的工作之一。

原创文章,作者:速盾高防cdn,如若转载,请注明出处:https://www.sudun.com/ask/76286.html

Like (0)
速盾高防cdn的头像速盾高防cdn
Previous 2024年5月20日
Next 2024年5月20日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注