文章
技术

我亲自教大家做网站(2)

thphd  ·  2020年10月13日 2047前站长

在第一课中,我向大家介绍了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.3192.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协议,我下节课再讲。

菜单
  1. 中野梓 轻音部
    中野梓   好无聊~

    按照这个进度,真要会做网站大概得等到明年

  2. 邹韬奋 外逃贪官CA
    邹韬奋   虽然韬光养晦,亦当奋起而争(拜登永不为奴:h.2047.one)

    我的操作指南: 买一个VPS,装linux(随便什么distro),然后装nginx,最后放一个index.html上面写个hello world,完成第一章。 第二章,直接下个开源的论坛框架,套上去,配置好admin账户,做一个强密码,然后开张。测试通过,第二章结束。

  3. thphd   2047前站长

    @消极 #103173 you can of course do that, but that only gives you the illusion of freedom.

  4. goodidea 想被玩坏
    goodidea   我好想被最心爱的人玩坏,反正感觉自己活不久了,还不如被玩坏呢

    手机版支持不好,右面的东西看不到

  5. 琳不可瑤混 小朋友
    琳不可瑤混   你們可不能混瑤哦!

    又學到新東西了,好快樂啊

  6. 邹韬奋 外逃贪官CA
    邹韬奋   虽然韬光养晦,亦当奋起而争(拜登永不为奴:h.2047.one)