网络 概念初识。
本系列文章将帮助大家了解网络是如何运作的。
身为一个 Web 应用程序员,你需要知道当我们在网页浏览器的地址栏输入一个网址回车后,背后到底发生了哪些事情。
本节将介绍一下网络相关的基本概念。
引子
让我们从一个简单的类比入手:
电脑网络跟传统电话有什么不一样?
传统的电话使用的是电路交换的方式:呼叫方拨打电话后,中间经过电话交换机将线路接到受话方。讲话时整条线路被完全占用,一条电话线同时间只能一个人讲话。
电脑网络使用的是数据包交换的方式:把要传输的数据拆成适当的块(如 1500 bytes),每个块叫做数据包(Packet)。每个数据包有个 首部(Header)会写上接收方的地址,和 要传输的数据本身 叫做负载(Payload),然后再通过网络传输。
像寄信一样,我们把要寄的东西放在信封里,这个信封可以想像成数据包的 Header,信封里面的东西是 Payload。
数据包交换网络比传统的电路交换网络 更有效率 。因为拆成数据包后,线路可以让大家共享,不同人不同电脑可以同时传输不同数据,最佳化整个线路的连线负载能力。
网络分层设计
网络传输有一个非常重要的设计就是分层(Layer),实务上被分为四层:(有的书可能会将 OSI 理论模型分成七层,这里采用实务的 RFC 1122 说法)
- 数据链路层 (Link Layer):用来处理局部网中 硬件 连接的传输(例如 Etherent 协议、无线网络 802.11n 协议、3G/4G 手机网络)
- 网络层 (Internet Layer):用来处理因特网中的 网络设备 和网络设备之间的传输(例如 IP 协议)
- 传输层 (Transport Layer):用来处理 电脑 到电脑之间的可靠传输(例如 TCP 和 UDP 协议)
- 应用层 (Application Layer),网络 应用程序 之间如何处理数据(例如 HTTP 协议)
你可以想像分层的意思就是数据包了四个信封。当我们的浏览器打开一个网站,服务器回传的 HTML 源码是最里面的 Payload,而它会被包在 HTTP 信封内,然后再包一层 IP 信封,然后再包一层 TCP 信封,然后再包一层 Etherent 信封,才会抵达你的电脑:
—————————————————————————————————————————————————————————————
| Etherent 首部 | IP 首部 | TCP 首部 | HTTP 首部 | 实际的数据 HTML 源码 |
—————————————————————————————————————————————————————————————
这样设计的好处是某一层如果需要改变,只需要替换那一层信封就好了。而且层次化之后,要设计新协议也会简单许多,我们不需要每次都重新设计全部的协议。
下面我们简单介绍下每一层。
数据链路层 (Link Layer) - 硬件之间
家里或公司电脑要上网,首先必须接上网络线或用无线网络,来连结到家或公司的路由器(Router)。这之间需要一层信封写上电脑地址,这样路由器把数据传回时,才知道送到哪台电脑上。
这一层的传输协议根据不同的硬件连接方式有不同的协议,最常见的有:
- 有线网络使用 以太网 (Ethernet) 协议。这种硬件使用 RJ-45 网络线(拧成4对的8根电线),又可以细分为 100M、1000M 不同的规格。
- 无线网络的 IEEE 802.11 协议,又可以分成 802.11b, , 802.11g, 802.11n 等不同规格。
- 移动通信网络使用 3G、4G 协议。
每一个网络设备在出厂时,都会配有一个 Mac 地址 (Media Access Control Address),这个地址将用于「直接」相连在一起的硬件。例如连结到同一台路由器的公司电脑,这台路由器收到数据包就会用 Mac 地址来决定将这个数据包寄回到哪一台去(我们会说:这是同一个局域网)。
命令行输入 ifconfig
可以看 Mac 地址:
在 Mac 电脑上查看对应的接口(第一个)。这对应的就是你的无线网卡:
当你有数据要传到公开网站时,首先会从你电脑传到家里或公司的路由器,信封会填上 Mac 地址,然后发送出去。路由器收到之后,会把这一层的信封拆掉,换上与路由器直接连接的 ISP(Internet Service Provider,互联网服务供应商,如中国移动、中国联通的因特网运营商) 路由器的 Mac 地址,然后寄到下一个网络硬件设备,以此类推直到目的地网站服务器。
网络层 (Internet Layer) - 网络设备之间
前面介绍的数据链路层使用的 Mac 地址,只有直接相连网络设备才会互相知道。比如你的电脑知道它链接的路由器的 Mac 地址、路由器知道跟他连结的设备的 Mac 地址。但我们不知道家或公司路由器出去之后的网络设备的 Mac 地址,我们也不可能知道网上所有网络设备 Mac 地址。
互联网的节点数很多,数据包是由一个路由器传递给下一个路由器,每个传递都更接近目的地。而这个目的地需要一个地址,而这就是 IP 协议所处理的。
在 IP 协议中定义了 IP 地址 ,其中第四版 IPv4 由 4 bytes(32位二进制)的数字组成,就是常看到的 XXX.XXX.XXX.XXX
形式。
这个 IP 地址是全球唯一的,IP 地址最多可有 4,294,967,296
个,乍看好像很多,但由于互联网大量普及,IPv4 的 42 亿个地址的分配已经于 2011 年 2 月 3 日全部分配完毕,分给不同国家、公司组织、学校等使用。
IP 地址设计时保留了一些私有 IP 地址用于局域网,最常见的是 192.168.0.0
到 192.168.255.255
这个范围,你在家里或公司连上无线路由器时,就会被分配到这个地址。另外还保留一个 127.0.0.1
代表本机电脑,私有 IP 地址。
几个小知识点:
CIDR 是一种 IP 位址的表示法,用来表示一整个区块的 IP 位置。(在配置网络防火墙的时候会用到)a.b.c.0/16
:a.b.0.0
到a.b.255.255
,共 65,536 个地址a.b.c.0/24
:a.b.c.0
到a.b.c.255
,共 256 个地址a.b.c.0/32
:a.b.c.d
一个地址
既然 IPv4 地址不够了,新标准 IPv6 使用了 16 bytes 来表示网络位置,具体数量为340,282,366,920,938,463,463,374,607,431,768,211,456
个,真的用不完了。不过对一般用户似乎很少用到。这是因为要使用 IPv6,必须客户端到服务器中间的网络设备都要支持 IPv6,而大部分的 ISP 营运商都还没默认支援 IPv6。Apple 要求从 2016/6/1 开始,所有上架的 App 必须 IPv6 兼容。
NAT 技术
刚提到 IPv4 的42亿个地址已经被分配完,但大家不是很着急要升级 IPv6 这件事情,这是什么原因?
这是因为我们用了 NAT 技术,因此不需要每一台需要上网的电脑都有一个公开的 IP。
透过 NAT 技术,家里或公司只有路由器那一台网络设备需要公开的 IP 地址,局域网内使用私有 IP 地址即可。这台路由器会记得当初数据包是从拿一台电脑送出来的,当数据包从因特网返回时,会有一个 IP 地址转换。
这也是因为局域网内的电脑只需要上网,不需要做成服务器让因特网上的其他电脑可以连线。换言之,一台电脑如果要是因特网上可以被连线的服务器,必须要有一个公开的 IP 地址。
同样,命令行输入 ifconfig
可以看 IP 地址,并在 Mac 电脑上查看对应的参数:
这里多介绍几个知识点:
上图中的:
- DHCP 协议 指当电脑连上路由器时,会自动请路由器分配一个局域网的私有 IP 地址给你。
- Subnet Mask 指这个局域网的 IP 范围,其中
255.255.255.0
意思是整段私有 IP 地址数字前面 24bit 是固定的,也就是范围会是192.168.1.1
到192.168.1.255
。 - Router(路由器)的地址是
192.168.1.1
,你的数据包首先会送到这台网络设备,由路由路决定下一站去哪里。 - 另外 broadcast 地址
192.168.1.255
是向全局域网广播的地址,结尾.255
是广播的意思。
ping 指令
ping
可以用来测试数据包送到目的地所需时间。其中 time 是 RTT(Round Trip Time) 也就是往返时间,单位是 ms (千分之一秒)。
这个时间主要取决于地理位置。如果你在北京去 ping 国内大陆网站,会得到超快的速度;如果去 ping 台湾或日本的服务器会慢点,去 ping 美国的服务器要 200ms (例如 github.com),要去欧洲或南美洲就更远了。
这个速度的物理限制是光速,要去美国的海底电缆是走太平洋,往返到地球另一端就是需要这么多时间。这就是为什么网站的连线速度要好,就得把服务器离用户比较近的原因。
Tips:不是每一台服务器都会回应 ping 信息,有些服务器会关闭此功能。
traceroute 指令
traceroute
用来追踪到达目的地过程中,每台路由器节点的回应。
Tips:和 ping
一样,不是每台路由器都会回应这个信息,有些路由器会关闭这个功能。
传输层 (Transport Layer) - 电脑之间
IP 数据包有 IP 地址可以抵达对方电脑,但是一台电脑上有很多不同的应用程序,到底这个数据包抵达对方电脑后要给哪个程序处理呢? 同理,数据包送回后,又是你电脑的哪个程序去处理?
在传输层协议 TCP 和 UDP 中定义了 Port number,在数据包首部会写上 来源埠(Source Port Number)和 目的埠(Destination Port Number)。Port Number 就像不同码头,编号从 0~65535。
以客户端浏览器发出的数据包为例,浏览器会随机选一个来源埠出去,目的埠会是 80 (http)
或 443 (https)
,除非你在浏览器自行指定不同的目的埠,例如 http://localhost:3000
,那就会改用 3000 port
,因为 rails s
服务器在本机默认用 3000 port
。(localhost
会被解析成 127.0.0.1
代表本机地址)
服务器会用哪些 Port 可以看 TCP/UDP埠列表,不同的应用程序就会用不同的 Port。每一个需要用到网络的程序,都必须跟操作系统登记申请一个 Port 来使用,操作系统会确认一个 Port 只能分给一个程序使用。
如果你要编号 1024
以下的话,操作系统还会要求你有 root
权限。1024
以上则不需要。
例如 rails 服务器就默认使用了 Port 3000
,本博客的 hexo
则用了 Port 4000
。
另外,IP 协议让我们可以将数据包从因特网的一端传到另一端,但没保证数据包的可靠传输。传输过程中可能被中间的路由器丢失(有意或无意、网络壅塞丢包、外界噪声干扰s等),不同数据包也可能因为经过不同路由器而造成抵达顺序不同。
因此在 TCP 协议中用了更多步骤来保证传输的正确性(包括会重发遗失的封包、舍弃重复的封包、无错误资料传输、阻塞/流量控制、确认有建立三方交握,连线已建立才作传输等算法)。TCP 是个非常复杂的协议,也是使用最广泛的协议,和 IP 协议合称 TCP/IP
,下面将要提到的大部分的应用层协议,包括 HTTP 都是基于 TCP/IP 的。
(TCP/IP 是大学本科网络概论课的重头戏,会完整介绍如何实作 TCP 协议。TCP/IP 的首部是二进制格式,这里就不讲规格细节了。推荐阅读阮一峰博客《TCP 协议简介》)
相关工具
通过 Wireshark 或 Packet Peeper 之类的软件可以进行网络封包的撷取:
应用层 (Application Layer) - 应用程序之间
TCP/IP
协议是操作系统本身会提供的网络功能,而在我们电脑上会有不同的应用软件会基于 TCP/IP
实现应用层协议,例如:
- DNS
- HTTP
- SSH
- FTP (文件传输)
- SMTP (寄email)(推荐阅读阮一峰博客《如何验证 Email 地址:SMTP 协议入门教程》)
- POP (收email)
- SMB (微软的网络文件共享系统)
- Bitcoin(比特币)
- BitTorrent
其中最常用的就是 DNS 协议 和浏览器使用的 HTTP 协议 了,接下来详述这两个协议。
拓展阅读
网络概论(一) :网络 概念初识。
网络概论(二) :DNS 原理入门。
网络概论(三) :HTTP (Hypertext Transfer Protocol-超文本传输协议)入门。