本文简单介绍一些计算机网络相关的专业知识
众所周知,计算机网络最重要的概念是 OSI 七层模型
OSI 七层模型
自底向上,分为以下七层
- 物理层,完成 bit 到载波之间的转换,处理物理介质接口
- 数据链路层,负责介质访问控制和逻辑链路控制
- 网络层,负责主机到主机之间的通信与路由寻址
- 传输层,负责进程间端到端通信和可靠传输
- 会话层,负责会话的建立、撤销与面向连接的口令认证等
- 表示层,负责信息的加密、解密、压缩、转换等
- 应用层,提供最通用的应用程序(电子邮件、web等),完成用户与软件的交互
然后先介绍一下重要的协议们
- 网络层,IP 协议
- 传输层,TCP 协议
- 应用层,HTTP 协议
- 介于网络层和传输层之间,SSL 协议
IP 协议
网络层负责路径确定与逻辑寻址
而路径,就是由 IP 地址提供的,通过点分十进制计数法确定 IPv4 地址
但是显然 IP 地址总数是有限的,怎么延长寿命呢?
1985 年起增加 “子网号字段”,IP 地址变为 网络号+子网号+主机号
其中,主机号全 0 代表网络,主机号全 1 代表广播
这样,网络数量就增加了,但还是不够用,于是又产生了 网络地址转换——NAT
根据网络的 ABC 类,分配不同的私有地址,私有地址是同一路由器内特有的
常见的民用 IP 地址是 C 类,私有地址就是 192.168.0.0/16, 16 指子网掩码
为了 IP 协议的正常运转,又产生了 差错报告机制——ICMP,我们知道的 ping 命令测试网络连接可达性,就是基于 ICMP 的
而且 ping 命令是应用层直接使用 网络层 ICMP 的,并没有经过传输层的 TCP 或 UDP
一个 ping 实例如下
| 1 | ping baidu.com | 
TCP 协议
传输层有 TCP 协议和 UDP 协议,其中 TCP 协议负责端到端连接、可靠性和流量控制
TCP 的特点如下
- 面向连接
- 点对点
- 可靠
- 全双工
- 字节流
相对的 UDP 的特点如下
- 无连接
- 尽力交付
- 面向报文
- 允许广播
因为 TCP 有 UDP 所没有的最重要的机制 —— 三次握手、四次挥手,所以 TCP 传输会比 UDP 安全很多,也易于控制,但是也因此在连接上消耗了更多时间,传输速率不如 UDP 快
TCP 的主要机制如下,其特点全部依赖其机制
- 应答机制、超时机制、重传机制、窗口机制
- 流量控制:滑动窗口机制
- 拥塞控制:慢开始、拥塞避免、快重传、快恢复、随机早期检测
- 连接的建立和解除:三次握手、四次挥手
虽然实际的数据报交换还是网络层在负责,但传输层解决了网络层的主要问题:丢包、重复、乱序
为什么可以解决这些问题呢?因为网络通信本质上是两个进程间的通信,而不是主机之间的通信
通信中由 IP 地址唯一标识主机,由端口号唯一标识进程,所以可以通过 IP 地址+端口号的形式来进行进程间通信
而传输层又向上层隐藏了硬件拓扑、路由细节等,使得上层应用程序可以直接调用其接口,建立一条虚拟的端到端的通信信道
建立信道和解除的过程如下图


HTTP 协议
定义
万维网 WWW(World Wide Web)建立的原因,是一个美好的愿景:万物互联
万维网是分布式超媒体系统,是超文本系统的扩充
在万维网客户程序与万维网服务器程序之间进行交互所使用的就是超文本传输协议 HTTP,这是一个应用层协议,基于 TCP 进行可靠传输
URL
万维网通过”链接”的方法能主动地按需获取信息,不同的信息通过 统一资源定位符 URL 来标识
URL 的格式如下
<协议>://<主机>:<端口>/<路径>
此处的协议可以是 http、ftp、file 等,但本文只介绍 http 协议相关内容
协议版本
HTTP 1.0 协议是无状态的,HTTP 本身也是无连接的,虽然使用了基于 TCP 的可靠传输,但是每次通过 TCP 传输完毕后,该 TCP 连接都会被关闭
作为改进,HTTP 1.1 协议使用持续连接,指在收到服务器响应后,连接仍会保持一段时间,同一个客户和该服务器之间可以继续使用这条连接进行通信
域名系统
URL 中的主机号可以是 IP 地址,或一个域名,或一个计算机地址标识符
域名系统 DNS(Domain Name System)提供了将人类可读符号映射到计算机地址的服务(计算机地址不止是 IP 地址)
域名与计算机地址之间的关系是多对一,即一个域名只能映射到一个计算机地址,但一个计算机地址可以被多个域名所映射
域名的结构为 层次树状结构,由标号序列组成,各部分之间用 点号 隔开
但是如何知道域名和计算机地址的映射关系?需要通过 DNS 服务器来进行解析
每个 DNS 服务器负责一个区,此时该 DNS 服务器称为 权限域名服务器,用来保存该区中所有主机的域名到 计算机地址 的映射
包括 权限域名服务器,DNS 服务器自顶向下共有以下类型
- 根域名服务器 - 最重要的域名服务器。所有根域名服务器都知道所有顶级域名服务器的域名和 IP 地址 - 不论是哪一个本地域名服务器,只要这个本地域名服务器不能自己解析一个域名,就会首先求助根域名服务器 
- 顶级域名服务器 - 负责管理在自己注册的所有二级域名 - 响应可能是域名解析结果,也可能是下一步应当询问的域名服务器地址 
- 权限域名服务器 - 负责一个区的域名服务器 - 响应可能是域名解析结果,也可能是下一步应当询问的权限域名服务器地址 
- 本地域名服务器,也称为默认域名服务器 - 一般是客户端主机上设置的首选 DNS 服务器,也称为 ISP DNS 服务器 - 当主机发出 DNS 查询请求时,该请求报文首先发送给本地域名服务器 
显然查询 DNS 的请求是要经过多级中转的。如何决定查询顺序呢?
有两个阶段
- 递归查询:主机向本地域名服务器的查询 - 如果主机所询问的本地域名服务器不知道域名解析的结果,则本地域名服务器就以 DNS 客户的身份,向其他服务器继续发出查询请求报文 
- 迭代查询:本地域名服务器向根域名服务器及其他域名服务器的查询 - 如果本地域名服务器所询问的根域名服务器不知道域名解析的结果,则告诉本地域名服务器下一个查询目标服务器的地址,由本地域名服务器继续提交请求 
示意图如下

这是服务器上的 DNS 查询,但不是每次 DNS 查询都直接从本地域名服务器开始
DNS 查询流程按顺序一般如下
- 浏览器缓存
- 操作系统缓存
- 路由器缓存
- 主机上的 hosts 文件
- 本地域名服务器…
可以使用 nslookup [addr] 命令来解析目标域名
一个 nslookup 实例如下
| 1 | nslookup baidu.com | 
端口
此处特指软件意义上的端口,有别于交换机上的硬件端口
端口号一般是一个 16 为无符号整数,范围在 0 - 65536
一般 0 - 1023 号端口是服务保留端口,自己的项目最好不要启动在这些端口上,除非你知道自己在干什么
常用端口一般有 20、21、22、80、443 等
路径
对于静态资源服务器,路径一般与服务器所在的磁盘目录一一对应
对于动态服务器,路径一般是个逻辑路径,用以标识资源
在动态服务器的路径,一般采用 RESTFUL API 设计,用 URI 标识资源,用 HTTP 动词描述动作
一般在路径的末尾都有一个斜杠,除非该路径指向一个具体的静态文件
报文结构
HTTP 有两类报文:请求报文(request)和响应报文(response)
由于 HTTP 是面向文本的,所以报文中每个字段都是 ASCII 码串,长度不确定
报文都分为开始行、首部行和实体主体,分别对应 Chrome 控制台中看到的 General、Headers 和 Payload
在请求报文中,开始行就是请求行
可以在本地命令行通过 curl -v [url] 查看报文信息
一个 curl 实例如下
| 1 | curl -v baidu.com | 
HTTP 动词
显然请求方法是很重要的。通常有如下请求方法
| 方法 | 意义 | 
|---|---|
| OPTION | 向服务器请求一些构成请求的关键选项,例如允许的方法 | 
| HEAD | 向服务器询问,首部行中哪些头部是 required | 
| GET | 查 | 
| POST | 增 | 
| PUT | 改 | 
| PATCH | 部分改 | 
| DELETE | 删 | 
| TRACE | 用于环回测试 | 
| CONNECT | 用于代理服务器 | 
状态码
HTTP 状态码分为 5 大类
| 状态码 | 意义 | 
|---|---|
| 1xx | 通知 | 
| 2xx | 成功 | 
| 3xx | 重定向 | 
| 4xx | 客户端出错 | 
| 5xx | 服务器出错 | 
常见的有 200、301、302、304、401、403、404、415、500、502 等
SSL 协议
SSL 只有一个重点,就是 RSA 加密,可以查看本文 图解非对称加密
接下来介绍一下物理层和数据链路层
待续