在第一课中,我向大家介绍了HTML和CSS两种语言,教大家做自己的第一个网页。
今天我要介绍的是,怎样让别人通过网络,查看/浏览你做好的网页。
假设我现在有一个网页 a.html
,内容如下:
<h1>习近平必须下台</h1>
这个网页我自己可以用浏览器打开,但是我最终的目的是让全世界网民都能看到这个网页。要实现这个目标,有几个概念是必须要了解的。下面我就跟大家讲讲这几个一般人容易搞混的概念。
IP地址
网络上的每个设备,都必须有一个地址,包括你的电脑和手机也是这样,如果没有地址的话,就没有办法互相发送数据,就好比如果你家没有地址,别人就没办法把快递寄到你家。在计算机世界,这个地址叫IP地址,它是一个32位的二进制整数。
32位的二进制整数看上去像这样:01010101110100010110...
这个地址难读难记,所以一般我们把这个地址拆分成4个8位的二进制整数,然后把这4个数都换成10进制来表示,中间用点连接,例如 202.112.233.75
。
至于这个地址为什么要叫IP地址,诸位自己谷歌一下。
你的电脑如果可以上网,它肯定也有一个IP地址(通常是由路由器或者运营商分配的),这个地址在任何操作系统里都是可以看到的,具体怎么看,诸位自己谷歌一下。
你的电脑的IP地址,可能是192.168.1.35
或者10.0.0.4
这样的形式。注意,这个地址绝大多数情况下不是国际互联网地址,而是位于某个局域网中的地址。
国际互联网地址(俗称“公网IP”),就好比你居住的小区的地址(比如中国北京朝阳区XX路XX号);而局域网地址(俗称“内网IP”),就好比你家在小区里面的楼号和房号。
为什么IP地址要分成“公网”和“内网”两种地址呢?
理论上讲,32位二进制整数,能够表示的整数有42亿个(2^32 = 4294967296),但是这42亿个地址,不可能100%高效利用,这就好比你家的地址有20个汉字,而常用汉字有5000个,理论上20个汉字可以组成5000^20个不同的地址(天文数字),但是实际上是做不到的,因为快递员必须靠前缀(也就是你家地址最开头那几个字,比如“北京市朝阳区”)来决定一封信要送到哪里,而前缀不可能是汉字的随意组合,只能在有限的组合里面选择(全国的省市区是有限的),所以实际上可以使用的前缀数量是非常有限的。同理,你家地址能选择的后缀(也就是地址结尾的那几个字,比如“三巷6号2楼”)也是非常有限的。总之,邮政地址对汉字编码的利用率是低于1%的。
国际互联网,也是靠IP地址的前缀,来决定数据包(packets)的去向的,所以也存在同样的问题。理论上有42亿个地址,实际上能够有效分配到设备的地址,不到1亿。
而地球上联网的计算机数量,早就超过了一亿台。运营商想到的解决办法,就是不给消费者(互联网最底层的用户)的每一台计算机分配公网IP,而是每几百台、几千台、甚至几十万台计算机,分配一个公网IP,这些计算机组成一个内网,它们在内网可以通过内网IP互相连接访问,而当他们需要连接公网(比如使用google、facebook)的时候,再通过某种方式,共用一个公网IP地址。这就是为什么会有公网和内网两种地址。
正因如此,今天我们使用的互联网,是非对称的:你从内网可以访问公网的Google.com(因为Google买下了很多公网IP,没错,作为一种稀缺资源,IP地址是可以花钱买的),但是公网上的其他人,无法访问内网中的你(所以也就无法访问你电脑上的网页)。
但互联网并非一直都是这样。互联网刚刚步入平常百姓家的时候(1995年),不管是中国还是美国,宽带用户联网之后,都可以分配到公网IP,因为那个时候IP并不是稀缺资源。
光阴似箭,如今全世界互联网用户数量增长了几万倍,一个中国人如果想要在家庭宽带获得公网IP(用来开设网站),唯一的选择是中国电信宽带,报装之后打电话去客服申请,理由合理才能分配到公网IP。分配到的IP地址虽然是公网IP,却不是固定的,往往是一天一换或者三天一换。
正因如此,在自己家电脑上建网站,同时又要让世界各地的人能看到,并不是一件简单的事情,且有越来越困难的趋势。
小实验
怎么证明在国际互联网上,通过IP地址可以与另一台计算机通信呢?
其实有一些网站是支持通过IP地址直接访问的,以google为例,你可以先去https://mxtoolbox.com/DnsLookup.aspx,查询google.com
的IP地址,得到结果:
- 172.217.15.110
然后在浏览器里面访问http://172.217.15.110/,确实可以打开google。
小实验
国际互联网按照IP地址前缀,决定如何转发一个IP数据包,那么怎样才能知道我的数据包是如何被转发到目的地的(中间经过了几手、分别都是谁)?
- Windows用户请在开始菜单输入cmd回车,打开命令提示符窗口,输入
tracert baidu.com
,然后回车。 - OSX用户请打开“终端(Terminal)”应用,输入
traceroute baidu.com
,然后回车。
TCP协议
在一个IP网络(使用IP地址,实现数据定向发送和接收的网络)里,一台计算机可以向另一台计算机发送IP数据包。
假如你的电脑同时干两件需要联网的事情,比如说你一边用浏览器下载文件,同时又在用微信聊天,那么你就需要同时跟两台计算机进行IP通信,他们会同时向你发来很多很多的IP数据包。这些数据包被计算机操作系统收到以后,要分发给不同的应用程序,有的数据包要发给浏览器,有的数据包要发给微信客户端。
问题是,怎么确定哪个数据包要发给哪个应用程序?你可能会说,用发送方的IP地址来区分。那万一两个发送方使用的是同一个IP地址(你下载的微信安装包,跟你微信聊天的数据,都来自腾讯的同一个服务器),怎么办?
这个例子就说明,光有IP协议、IP地址是无法满足人们日常的网络使用需求的。于是工程师们决定,在IP协议的基础上,扩展一个新的协议,以使得一台计算机上的多个应用程序,能够同时和多台计算机上的多个应用程序进行连接,不同连接之间互不干扰。
工程师们最终决定,把IP地址延长一点点,在地址的后面,加一个叫“端口号(port number)”的东西,来区分不同的连接。端口号是一个16位的二进制整数,对应十进制的 0..65535。有了端口号以后,每台计算机不再是一个公用的大邮箱、大电报局,而被分成了六万个互相隔离的小邮箱、小电报局,使得同一台计算机上,不同的应用程序能够互不干扰地与远端的计算机通信。
换句话来讲,自从有了端口号,从一台计算机向另一台计算机,可以发起很多很多的网络连接,每一个连接都必须指定起点和终点的端口号,应用程序通过“占用”端口的形式,与远端计算机上的应用程序通信。
这种依赖于端口号的通信方式,或者叫通信协议,应用最广泛的,一个叫TCP,一个叫UDP。你的浏览器、微信客户端、网络游戏……可以说绝大多数联网的计算机程序,用的都是TCP或者UDP协议。TCP/UDP is everywhere.
TCP到底是怎么工作的呢?对于一个应用程序来说,可以像下面这样理解:
-
两台计算机的IP地址分别是
192.168.1.3
和192.168.1.4
。 -
在
192.168.1.3
上,有一个应用程序server.exe
,它跟操作系统说:我想占用12345号端口,等待其他计算机向我发起连接。 -
操作系统说:12345端口没有其他人占用,你可以占用了。
-
在
192.168.1.4
上,有一个应用程序client.exe
,它跟操作系统说:我想占用34567端口,同时向192.168.1.3:12345
发起连接。 -
操作系统说:34567端口没有其他人占用,你可以占用了。你想发些什么?
-
client.exe
说:我要发i hate xijinping
-
操作系统说:好的,我现在就把
i hate xijinping
这句话,贴上IP地址和端口号192.168.1.3:12345
,发给192.168.1.3
-
在
192.168.1.3
上,操作系统跟server.exe
说:嘿,收到一个数据包,目标端口号是12345,也就是发给你的,内容是i hate xijinping
。
小实验
当网页浏览器访问一个网站的时候,会向这个网站服务器的80端口(HTTP协议默认端口),发起一个TCP连接,告诉对方自己需要什么。我们可以手动模拟这个TCP通信的过程,来获取网页的内容。
-
Windows(7/10): 管理员权限运行CMD,输入
dism /online /Enable-Feature /FeatureName:TelnetClient
以启用Telnet功能。Telnet允许我们用键盘输入字符,来和远端计算机进行TCP通信。启用Telnet之后,输入
telnet baidu.com 80
,回车。这里我用了baidu.com,你也可以替换成百度的ip地址,效果是一样的。连接baidu.com的80端口成功后,CMD窗口会变成一片黑,此时以最快速度(慢了会因超时而断开),输入:
GET / HTTP/1.0[回车][回车]
;如果一切顺利,你会收到百度给你的回复,内容如下:
HTTP/1.1 200 OK
Server: Apache
Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
ETag: "51-47cf7e6ee8400"
Accept-Ranges: bytes
Content-Length: 81
Cache-Control: max-age=86400
Connection: Close
Content-Type: text/html
<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>
在百度返回的内容里面,包含一个HTML文档,文档内容的大意是:所有访问baidu.com的朋友,请跳转到www.baidu.com。
如果你在发起TCP连接的时候,把端口从80改成其他数字,比如85,连接将会失败,说明TCP协议确实是通过端口号来区分同一台计算机上的不同目标的。
如果我们能设计一个程序,像百度那样,“占用”计算机的80端口,“监听”或者叫“等待”来自其他计算机的TCP连接,每收到一个连接,我们就发一次HTML的网页过去,那么在其他计算机看来,我们就在这台计算机上,架设了一个可以用浏览器访问的网站。
具体的架设过程,以及HTTP协议,我下节课再讲。