计算机网络
网络的网络
网络把主机连接起来,而互联网是把多种不同的网络连接起来,因此互联网是网络的网络。
ISP
互联网服务提供商(Internet Service Provider)拥有通信线路以及路由器等联网设备,可以从互联网管理机构获得许多 IP 地址。个人或机构向 ISP 缴纳一定的费用就可以接入互联网。
目前的互联网是一种多层次 ISP 结构,ISP 根据覆盖面积的大小分为主干 ISP、地区 ISP 和本地 ISP。
互联网交换点(Internet eXchange Point)允许两个 ISP 直接相连而不用经过第三个 ISP。
互联网的组成
- 边缘部分:所有连接在互联网上的主机,用户可以直接使用;
- 核心部分:由大量的网络和连接这些网络的路由器组成,为边缘部分的主机提供服务。
主机之间的通信方式
客户-服务器(C/S):客户是服务的请求方,服务器是服务的提供方。
浏览器-服务器(B/S):浏览器是服务的请求方,服务器是服务的提供方。
对等(P2P):不区分客户和服务器。
电路交换、报文交换、分组交换
电路交换
电路交换用于电话通信系统,两个用户要通信之前需要建立一条专用的物理链路,并且在整个通信过程中始终占用该链路。由于通信的过程中不可能一直在使用传输线路,因此电路交换对线路的利用率很低,往往不到 10%。
报文交换
报文交换用于邮局通信系统,邮局接收到一份报文之后,先存储下来,然后把相同目的地的报文一起转发到下一个目的地,这个过程就是存储转发过程。
分组交换
分组交换也使用了存储转发,但是转发的是分组而不是报文。把整块数据称为一个报文,由于一个报文可能很长,需要先进行切分,来满足分组能处理的大小。在每个切分的数据前面加上首部之后就成为了分组,首部包含了目的地址和源地址等控制信息。
存储转发允许在一条传输线路上传送多个主机的分组,也就是说两个用户之间的通信不需要占用端到端的线路资源。相比于报文交换,分组比报文更小,因此分组交换的存储转发速度更快。
时延
总时延 = 发送时延 + 传播时延 + 处理时延 + 排队时延
- 发送时延:主机或路由器发送数据帧所需要的时间。
- 传播时延:电磁波在信道中传播一定的距离需要花费的时间,电磁波传播速度接近光速。
- 处理时延:主机或路由器收到分组时进行处理所需要的时间,例如分析首部、从分组中提取数据部、进行差错检验或查找适当的路由等。
- 排队时延:分组在路由器的输入队列和输出队列中排队等待的时间,取决于网络当前的通信量。
计算机网络体系结构
各层对应的网络设备
中继器、集线器 > 物理层
网桥、交换机 > 数据链路层
路由器 > 网络层
网关(不是设备) > 网络层(常见)
数据在各层之间的传递过程
在向下的过程中,需要添加下层协议所需要的首部或者尾部,而在向上的过程中不断拆开首部和尾部。
路由器只有下面三层协议,因为路由器位于网络核心中,不需要为进程或者应用程序提供服务,因此也就不需要运输层和应用层。
数据链路层
CSMA/CD 协议
CSMA/CD 全称:载波监听多点接入/碰撞检测
- 多点接入:说明这是总线型网络,许多计算机以多点的方式连接到总线上。
- 载波监听:每个站都必须不停地监听信道。在发送前,如果监听到信道正在使用,就必须等待。
- 碰撞检测:在发送中,如果监听到信道已有其它站正在发送数据,就表示发生了碰撞。虽然每一个站在发送数据之前都已经监听到信道为空闲,但是由于电磁波的传播时延的存在,还是有可能会发生碰撞。
整体过程:
- 准备发送,并在发前,检测信道。
- 检测信道:若忙:则不停检测;若空闲,并在96比特时间(帧间最小间隔)内保持空闲的话,就发送。
- 发送过程中不停检测,即网络适配器要边发边监听:
a.争用期内一直未检测到碰撞,则发送成功,回到阶段1。
b.失败:检测到碰撞,停止发送,并发送人为干扰信号,再采取指数退避算法,等待r倍512比特时间后,返回阶段2。如果重传达到16次仍不成功,则停止重传,向上报错。
MAC
MAC 地址是 6 字节(48 位)的地址,用于唯一标识网络适配器(网卡),一台主机拥有多少个适配器就有多少个 MAC 地址,例如笔记本电脑普遍存在无线网络适配器和有线网络适配器。
MAC 帧:
类型:标记上层使用的协议;
数据:长度在 46-1500 之间,如果太小则需要填充;
FCS:帧检验序列,使用的是 CRC 检验方法;
前同步码:只是为了计算 FCS 临时加入的,计算结束之后会丢弃。
TCP/IP 体系结构
TCP/IP 协议族是一种沙漏形状,中间小两边大,IP 协议在其中占用举足轻重的地位。
IP 地址分类,子网划分:
类 | 起始 | 网络号 | 主机号 | 最大可指派网络数 | 第一个网络号 | 最后一个网络号 |
---|---|---|---|---|---|---|
A | 0 | 8位 | 24位 | 2^7-2 | 1 | 126 |
B | 10 | 16位 | 16位 | 2^14-2 | 128.1 | 191.255 |
C | 110 | 24位 | 8位 | 2^21-2 | 192.0.1 | 223.255.255 |
D | 1110 | 多播 |
TCP/UDP 区别
基本区别:
- 基于连接与无连接
- TCP 要求系统资源较多,UDP 较少
- UDP 程序结构较简单
- 流模式(TCP)与数据报模式(UDP)
- TCP 保证数据正确性,UDP 可能丢包
- TCP 保证数据顺序,UDP 不保证
- TCP 的逻辑通信信道是全双工的可靠信道,UDP 则是不可靠信道
UDP 应用场景:
- 面向数据报方式
- 网络数据大多为短消息
- 拥有大量 Client
- 对数据安全性无特殊要求
- 网络负担非常重,但对响应速度要求高
三次握手和四次挥手
三次握手:互相确认对方都可以收也可以发。
四次挥手:互相确认对方都收到自己要关闭的信息,并且对方已经没有要传输的信息了。
三次握手例子:
第一次握手:A 打电话给 B:你可以听到我说话吗?
第二次握手:B 收到 A 的信息,回复:我可以听到你说话,你听得到我说话吗?
第三次握手:A 收到 B 的信息,回复:可以听到你说话,我要给你发信息啦!
三次握手之后,A 和 B 都能确定:我说的话,你能听到;你说的话,我也能听到。这样,就可以开始正常通信了。
如果是两次:无法确认发起方可以收到。
如果是四次:在三次已经可以确认时,增加次数可以提高通信的可靠性,不过会浪费资源而已。
四次挥手例子:
第一次挥手:A:喂,我不说了 (FIN)。
第二次挥手:B:我知道了(ACK)。等下,上一句还没说完。Balabala…..(传输剩余数据)
第三次挥手:B:好了,说完了,我也不说了(FIN)。
第四次挥手:A:我知道了(ACK)。
A 等待2MSL,保证 B 收到了消息,否则重说一次“我知道了(ACK)”。
四次挥手之后,把该说的话都说完,并且 A 和 B 都知道自己没话说了,对方也没花说了,然后就挂掉电话(断开链接)了。
滑动窗口
窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。
发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。
接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 32, 34, 35},其中 {31, 32} 按序到达,而 {34, 35} 就不是,因此只对字节 32 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。
可靠传输
TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。
一个报文段从发送再到接收到确认所经过的时间称为往返时间 RTT,加权平均往返时间 RTTs 计算:RTTs = (1 - a) x RTTs + a x RTT
超时时间 RTO 应该略大于 RTTs,TCP 使用的超时时间计算:RTO = RTTs + 4 x RTTd,其中 RTTd 为偏差。
流量控制
流量控制是为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接受,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四种算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量。注意拥塞窗口与发送方窗口的区别,拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
为了便于讨论,做如下假设:
- 接收方有足够大的接收缓存,因此不会发生流量控制;
- 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。
慢开始与拥塞避免
发送的最初执行慢开始,令 cwnd=1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 …
注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。
如果出现了超时,则令 ssthresh = cwnd/2,然后重新执行慢开始。
快重传与快恢复
在接收方,要求每次接收到报文段都应该发送对已收到有序报文段的确认,例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。
在发送方,如果收到三个重复确认,那么可以确认下一个报文段丢失,例如收到三个 M2 ,则 M3 丢失。此时执行快重传,立即重传下一个报文段。
在这种情况下,只是丢失个别报文段,而不是网络拥塞,因此执行快恢复,令 ssthresh = cwnd/2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。
应用层
域名系统 DNS
把主机名解析为 IP 地址,被设计成分布式系统。
层次结构
一个域名由多个层次构成,从上层到下层分别为顶级域名、二级域名、三级域名以及四级域名。所有域名可以画成一颗域名树。
域名服务器可以分为以下四类:
- 根域名服务器:解析顶级域名;
- 顶级域名服务器:解析二级域名;
- 权限域名服务器:解析区内的域名;
- 本地域名服务器:也称为默认域名服务器。可以在其中配置高速缓存。
区和域的概念不同,可以在一个域中划分多个区。在域 abc.com 中划分了两个区:abc.com 和 y.abc.com:
因此就需要两个权限域名服务器:
解析过程
主机向本地域名服务器解析的过程采用递归,而本地域名服务器向其它域名服务器解析可以使用递归和迭代两种方式。
迭代的方式下,本地域名服务器向一个域名服务器解析请求解析之后,结果返回到本地域名服务器,然后本地域名服务器继续向其它域名服务器请求解析;而递归的方式下,结果不是直接返回的,而是继续向前请求解析,最后的结果才会返回。
Web 页面请求过程
这个过程可以大致分为两个部分:网络通信和页面渲染。
网络通信
解析 URL
a.浏览器判断地址是否是通过域名访问的。
DNS 解析:从浏览器的缓存中去找网址对应的 IP 地址 ->
从 OS 系统的 DNS 缓存中找 ->
从路由器的 DNS 缓存中找 ->
从 ISP 的 DNS 缓存中找。如果都没有找到:向 ISP 或公共的域名解析服务发起 DNS 查找请求(递归查询)。
比如:baidu.com 查找过程: 根域名服务器 -> .com 域名服务器 -> baidu.com 域名服务器。
b.若地址不含端口号,则根据协议补充默认端口号。如 HTTP 协议是 80 端口,HTTPS 是 443 端口。
建立 TCP 连接
TCP 协议通过三次握手建立连接。
1️:客户端通过 SYN 报文段发送连接请求,确定服务端是否开启端口准备连接。状态设置为 SYN_SEND;
2️:服务器如果有开着的端口并且决定接受连接,就会返回一个 SYN+ACK 报文段给客户端,状态设置为 SYN_RECV;
3️:客户端收到服务器的 SYN+ACK 报文段,向服务器发送 ACK 报文段表示确认。此时客户端和服务器都设置为 ESTABLISHED 状态。
连接建立,可以开始数据传输了。
应用层客户端发送 HTTP 请求
HTTP 请求包括请求头和请求主体两个部分。
请求头包含了重要的信息:请求的方法(GET/POST)、目标URL、遵循的协议(HTTP/HTTPS/FTP…)、返回的信息是否需要缓存、客户端是否发送Cookie 等。
服务器接收数据
服务器在链路层接收到数据包,再层层向上直到应用层。这过程中包括在传输层通过 TCP 协议将分段的数据包重新组成原来的 HTTP 请求报文。
服务器响应请求
Web 服务程序接收到客户端发送的 HTTP 请求后,解析请求,查找客户端请求的资源,并返回响应数据。
响应 = 响应行 + 响应头 + 响应主体。
响应行:HTTP/版本号 状态码 状态信息(比如: HTTP/1.1 200 OK)
响应头:服务器设置的一些信息,比如 Cookie 等。
响应主体:要返回的资源,比如 HTML 文件。
页面渲染
浏览器渲染页面的过程:解析 HTML -> 构建 DOM 树 –> 构建渲染树 –> 布局渲染树 –> 绘制渲染树。
DOM 树:由 HTML 文件中的标签排列组成。
渲染树:由 DOM 树中加入 CSS 或 HTML 中的 style 样式形成,只包含需要显示在页面中的 DOM 元素,如
浏览器还没接收到完整的 HTML 文件时,就开始渲染页面,在遇到外部链入的脚本标签或样式标签或图片时,会再次发送 HTTP 请求重复上述的步骤。
在收到 CSS 文件后会对已经渲染的页面重新渲染,加入它们应有的样式,图片文件加载完立刻显示在相应位置。在这一过程中可能会触发页面的重绘或重排。
GET 和 POST 区别
GET:请求获取指定的资源,报文主体没有任何语义。
- 安全
- 幂等(任意多次请求所产生的响应均与一次执行的响应相同)
- 可缓存的(除非有 Cache-ControlHeader 约束)
POST:根据请求负荷(报文主体)对指定的资源做出处理,具体的处理方式视资源类型而不同。
- 不安全
- 不幂等
- (大部分实现)不可缓存
这里指的“安全”在不同情况下是有不同解释的:
- 网络安全:两者都是一样的,HTTP 下两者都是明文,HTTPS 下两者都是密文。
- RFC2616 9.1.1:GET 被称为安全方法,而 POST 却不是,因为 GET 和 HEAD 方法应该只用于检索数据,而不是添加、更新和删除。
HTTP 状态码
状态码 | 意义 |
---|---|
1xx | 信息,服务器收到请求,需要请求者继续执行操作 |
2xx | 成功,操作被成功接收并处理 |
3xx | 重定向,需要进一步的操作以完成请求 |
4xx | 客户端错误,请求包含语法错误或无法完成请求 |
5xx | 服务器错误,服务器在处理请求的过程中发生了错误 |
HTTP/1.0 和 HTTP/1.1 区别
HTTP/1.1 支持长连接(PersistentConnection)
HTTP/1.0 会话方式:
- 建立连接
- 发出请求信息
- 回送响应信息
- 关掉连接
HTTP/1.0 规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。
HTTP/1.1 支持持久连接, 并且默认使用该方式,但也需要增加新的请求头来帮助实现。例如,请求头的值为 Keep-Alive 时,客户端通知服务器返回本次请求结果后保持连接;请求头的值为 close 时,客户端通知服务器返回本次请求结果后关闭连接。
HTTP/1.1 请求的流水线(Pipelining)处理
请求的流水线(Pipelining)处理,在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟。
例如,一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。
HTTP/1.1 允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容。
HTTP/1.1 Host 字段
HTTP/1.0 中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的 URL 并没有传递主机名(Hostname)。
但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。
HTTP/1.1 的请求消息和响应消息都应支持Host头域,且请求消息中如果没有 Host 头域会报告一个错误(400 Bad Request)。此外,服务器应该接受以绝对路径标记的资源请求。
HTTP/1.1 状态码 100(Continue)
客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就返回响应码 401(Unauthorized);如果服务器接收此请求就回送响应码 100,客户端就可以继续发送带实体的完整请求了。
优点:允许客户端在发送完整请求前先用请求头试探服务器,确认服务器是否接收,再决定要不要继续发。(节约带宽)
HTTP/1.1 Chunked transfer-coding
发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后用一个零长度的块作为消息结束的标志。这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。
HTTP/1.1 Cache 的新特性
当缓存对象的 Age 超过 Expire 时变为 stale 对象,Cache 不需要直接抛弃 stale 对象,而是与源服务器进行重新激活(revalidation)。
HTTP 缓存机制
Pragma:用来包含实现特定的指令,最常用的是Pragma:no-cache。(HTTP/1.1 协议中,含义和 Cache-Control:no-cache相同)
Expires:文件在本地缓存的过期时间,如果浏览器发现缓存中的文件没有过期,则不发送请求(有例外,后面介绍)。
Cache-Control:指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置 Cache-Control 并不会修改另一个消息处理过程中的缓存处理过程。
请求中的缓存指令:no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached。
响应中的指令:public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。
public:响应可被任何缓存区缓存。
private:对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请 求无效。
no-cache:请求或响应消息不能缓存。
no-store:防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age:客户端可以接收生存期 >= 指定时间(以秒为单位)的响应。
min-fresh:客户端可以接收响应时间 < 当前时间加上指定时间的响应。
max-stale:客户端可以接收 > 超时期间的响应消息。
Session 和 Cookie 区别
- Cookie 放在客户端,Session 放在服务器。
- Cookie 不安全。黑客可以分析存放在本地 Cookie 并进行 Cookie 欺骗。
- Session 会在一定时间内保存在服务器上。当访问增多,会占用你服务器的性能。
- 单个 Cookie 保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个 Cookie。
实现 Session 有两种方式:
- Cookie 实现。如果浏览器支持 Cookie,创建 Session 的时候把 SessionID 放在 Cookie 里。
- 重写 URL。如果浏览器不支持 Cookie,服务端可以通过重写 URL 的方式实现 Session,即 URL 后面加上 SessionID。
DNS 解析过程
操作系统首先检查本地的 hosts 文件是否有这个网址映射关系:
-> yes.就先调用这个 IP 地址映射,完成域名解析。
-> no.查找本地 DNS 解析器缓存,是否有这个网址映射关系:
——> yes.直接返回,完成域名解析。
——> no.首先找TCP/IP 参数中设置的首选 DNS 服务器,暂且叫它本地 DNS 服务器:
———–> 1.查询的域名,在服务器的本地配置区域资源中,返回解析结果给客户端,完成域名解析。
———–> 2.不由本地 DNS 服务器区域解析:
—————> a.但服务器缓存了此网址映射关系,则调用这个 IP 地址映射,完成域名解析。
—————> b.本地 DNS 服务器本地区域文件与缓存解析都失效,则根据本地 DNS 服务器的设置(是否设置转发器)进行查询:
——————-> a) 未用转发模式:本地 DNS 就把请求发至根 DNS,根 DNS 服务器收到请求后会判断这个域名由谁授权管理,并返回一个负责该顶级域名服务器的一个 IP。
———————> 1.本地 DNS 服务器收到 IP 信息后,将会联系负责该域名的这台顶级域名服务器。
———————> 2.顶级域名服务器收到请求后,如果自己无法解析,就会找一个管理该域名的下一级 DNS 服务器地址给本地 DNS 服务器。
———————> 3.本地 DNS 服务器收到这个地址后,就会找这个下一级 DNS 服务器服务器,重复上面的动作进行查询,直至找到域名主机。
——————-> b) 转发模式:本地 DNS 服务器就会把请求转发至上一级 DNS 服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根 DNS 或把转请求转至上上级,如此循环。
——————-> 不管是本地 DNS 服务器用的是转发,还是根提示,最后都是把结果返回给本地 DNS 服务器,再由本地 DNS 服务器返回给客户端。
从客户端到本地 DNS 服务器是递归查询,而 DNS 服务器之间的交互查询是迭代查询。
常用协议端口
端口 | 协议 |
---|---|
20/TCP | FTP 文件数据传输 |
21/TCP | FTP 控制信令的传输 |
23/TCP | TELNET 终端仿真 |
25/TCP | SMTP 简单邮件传输 |
53/UDP | DNS 域名解析 |
67/TCP | DHCP 服务端 |
68/TCP | DHCP 客户端 |
69/UDP | TFTP 简单文件传输 |
80/TCP | HTTP 超文本传输 |
110/TCP | POP3 邮局协议版本3 |
443/TCP | HTTPS 加密的超文本传输 |
1521/TCP | Oracle 数据库 |
1863/TCP | MSN Messenger 文件传输 |
3389/TCP | Microsoft RDP 微软远程桌面 |
5631/TCP | Symantec pcAnywhere 远程控制数据传输 |
5632/UDP | Symantec pcAnywhere 主控端扫描被控端 |
5000/TCP | MS SQL Server |