通过这本书了解到客户端(浏览器)发出请求到服务器返回响应这一过程中发生了哪些事情,网络中各种设备怎么协调工作,最终达到用户的需求。
完整的请求过程如下:
浏览器(发送请求) –> TCP/IP协议 –> 网卡驱动 –> 集线器 –> 路由器 –> 接入网 –> 电话局 –> 网络运营商 –> (光纤、双绞线) –> 网络运营商 –> 电话局 –> 接入网 –> 防护墙 –> 缓存服务器 –> 网卡驱动 –> TCP/IP协议 –> 服务器程序
浏览器:
生成 HTTP 请求消息
浏览器的第一步工作就是对输入的 URL 进行解析。URL开头表示访问数据源的机制,也就是协议(http或者ftp),“//”后面的字符串表示服务器的名称“www.baidu.com”, 接着表示数据源(文件)的路径名。HTTP 中主要的头字段
1 条请求消息中只能写 1 个 URI。如果需要获取多个文件,必须对每个文件单独发送 1 条请求。
向 DNS 服务器查询 Web 服务器的 IP 地址
Socket 库是用于调用网络功能的程序组件集合,提供查询 IP 地址的功能。根据域名查询 IP 地址时,浏览器会使用 Socket 库中的解析器。全世界 DNS 服务器的接力
DNS 服务器会从域名与 IP 地址的对照表中查找相应的记录,并返回 IP 地址。 客户端(www.baidu.com) –> 最近的DNS服务器 –> 根域 –> com –> baidu –> www, 可以通过缓存加快 DNS 服务器的响应委托协议栈发送消息
向操作系统内部的协议栈发出委托时,需要按照指定的顺序来调用 Socket 库中的程序组件。(1)创建套接字(创建套接字阶段)(2)将管道连接到服务器端的套接字上(连接阶段)(3)收发数据(通信阶段)(4)断开管道并删除套接字(断开阶段) 应用程序是通过“描述符”这一类似号码牌的东西来识别套接字的。描述符:应用程序用来识别套接字的机制;IP 地址和端口号:客户端和服务器之间用来识别对方套接字的机制TCP/IP
TCP在网络包出错丢失时可以重发,所以浏览器、邮件等一般应用程序收发数据时用 TCP(需要连接),这可能会浪费性能,DNS 查询等收发较短的控制数据时用 UDP(不需要连接)
套接字的实体就是通信控制信息:例如通信对象的 IP 地址、 端口号、 通信操作的进行状态等。协议栈是根据套接字中记录的控制信息来工作的。
通信操作中使用的控制信息分为两类。
(1) 头部中记录的信息
(2) 套接字(协议栈中的内存空间)中记录的信息TCP连接过程(3次握手)
(1) 连接操作的第一步是在 TCP 模块处创建表示连接控制信息的头部。
(2) 通过 TCP 头部中的发送方和接收方端口号可以找到要连接的套接字。将头部中的控制位的 SYN 比特设置为 1
(3) TCP 模块会将信息传递给 IP 模块并委托它进行发送;服务端IP模块接收到数据传给TCP模块,根据 TCP 头部中的信息找到端口号对应的套接字,从处于等待连接状态的套接字中找到与 TCP 头部中记录的端口号相同的套接字就可以了。 (第一次握手)
(4) 服务器的 TCP 模块会返回响应, 这个过程和客户端一样, 需要在 TCP 头部中设置发送方和接收方端口号以及 SYN 为1。此外,在返回响应时还需要将 ACK 控制位设为1, 设置ACK 比特就是用来进行确认网络包是否到达; (第二次握手)
(5) 客户端也需要将 ACK 比特设置为 1 并发回服务器, 告诉服务器刚才的响应包已经收到。 (第三次握手)收发数据
MTU:一个网络包的最大长度,以太网中一般为 1500 字节。
MSS:除去头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
对较大的数据进行拆分,使用 ACK 号确认网络包已收到。通过“序号”和“ACK 号”可以确认接收方是否收到了网络包。断开连接并删除套接字(完成数据发送的一方会发起断开过程:4次挥手)
(1) 连接方断开方协议栈会生成包含断开信息的 TCP 头部, 具体来说就是将控制位中的 FIN 比特设为 1
(2) 当收到连接方发来的 FIN 为 1 的 TCP 头部时,接受方协议栈会将自己的套接字标记为进入断开操作状态。 然后, 为了告知连接方已收到 FIN 为 1 的包, 会向连接方返回一个 ACK 号
(3) 数据全部接收后,接收方会生成一个 FIN 比特为 1 的 TCP 包, 然后委托 IP 模块发送给连接方。
(4) 连接方会返回ACK 号,通信结束。(两方ACK号对比确认数据成功传达)无论要收发的包是控制包还是数据包,IP 对各种类型的包的收发操作都是相同的。
IP 模块负责添加如下两个头部。
(1) MAC 头部:以太网用的头部,包含 MAC 地址
(2) IP 头部:IP 用的头部,包含 IP 地址
IP 头部的“接收方 IP 地址”填写通信对象的 IP 地址。发送方 IP 地址需要判断发送所使用的网卡,并填写该网卡的 IP地址。
IP 模块根据路由表 Gateway 栏的内容判断应该把包发送给谁。
将 IP 包转换成电或光信号发送出去
UDP
数据很短, 用一个包就能装得下,就不需要建立和断开连接的步骤,出错时重新发送一次就行,不用多次确认。
音频和视频数据:必须在规定的时间发送(实时),就算其中出错了,也只会造成失真和卡顿。
无需重发数据, 或者是重发了也没什么意义的情况下, 使用 UDP 发送数据的效率会更高。
集线器、交换机和路由器
每个包都是独立传输的
防止网线中的信号衰减很重要
“双绞”是为了抑制噪声
集线器将信号发送给所有连接在它上面的线路
交换机端口的 MAC 模块不具有 MAC 地址。交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口
交换机的全双工模式可以同时发送和接收信号
路由器的各个端口都具有 MAC 地址和 IP 地址。路由器根据“IP 地址”判断转发目标。路由器会忽略主机号,只匹配网络号
路由表的子网掩码列只表示在匹配网络包目标地址时需要对比的比特数量
路由器的端口都具有 MAC 地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃
通过路由器转发的网络包,其接收方 MAC 地址为路由器端口的 MAC 地址。路由表中子网掩码为 0.0.0.0 的记录表示“默认路由”
路由器判断下一个转发目标的方法如下
(1) 如果路由表的网关列内容为 IP 地址,则该地址就是下一个转发目标
(2)如果路由表的网关列内容为空,则 IP 头部中的接收方 IP 地址就是下一个转发目标IP(路由器)负责将包送达通信对象这一整体过程,而其中将包传输到下一个路由器的过程则是由以太网(交换机)来负责的
接入网和网络运营商
互联网接入路由器会在网络包前面加上 MAC 头部、PPPoE 头部、PPP 头 部 总 共 3 种 头 部, 然 后 发 送 给 ADSL Modem(PPPoE 方式)
ADSL Modem 将包拆分成信元,并转换成电信号发送给分离器
DSLAM 具有 ATM 接口,和后方路由器收发数据时使用的是原始网络包拆分后的 ATM 信元形式
BAS 负责将 ATM 信元还原成网络包并转发到互联网内部
PPPoE 是将 PPP 消息装入以太网包进行传输的方式
互联网接入路由器通过 PPPoE 的发现机制查询 BAS 的 MAC 地址
BAS 下发的 TCP/IP 参数会被配置到互联网接入路由器的 BAS端的端口上,这样路由器就完成接入互联网的准备了
BAS 在收到用户路由器发送的网络包之后,会去掉 MAC 头部和PPPoE 头部,然后用隧道机制将包发送给网络运营商的路由器
一对一连接的端口可以不分配 IP 地址,这种方式称为无编号
PPPoA 方式不添加 MAC 头部和 PPPoE 头部,而是直接将包装入信元中。
还有一种 DHCP 方式,它不使用 PPP,而是将以太网包直接转换成 ADSL 信号发送给 DSLAM
网络包通过接入网之后,到达运营商 POP 的路由器
互联网内部使用 BGP 机制在运营商之间交换路由信息
服务器端的局域网
防火墙: 包过滤方式的防火墙可根据接收方 IP 地址、发送方 IP 地址、接收方端口号、发送方端口号、控制位等信息来判断是否允许某个包通过
负载均衡: 通过将请求平均分配给多台服务器来平衡负载
缓存服务器分担负载:缓存服务器使用的代理机制放在客户端一侧—-正向代理:使用正向代理时, 一般需要在浏览器的设置窗口中的“代理服务器”一栏中填写正向代理的 IP 地址, 浏览器发送请求消息的过程也会发生相应的变化,设置浏览器非常麻烦, 如果设置错误还可能导致浏览器无法正常工作;通过将请求消息中的 URI 中的目录名与 Web 服务器进行关联, 使得代理能够转发一般的不包含完整网址的请求消息。—- 反向代理;查看请求消息的包头部。 因为包的 IP 头部中包含接收方 IP 地址, 只要知道了这个地址, 就知道用户要访问哪台服务器了 —- 透明代理
利用内容分发服务分担负载:CDS/CDN 让用户访问最近的缓存服务器, 不应采用轮询方式, 应该判断客户端与缓存服务器的距离, 并返回距离客户端最近的缓存服务器IP 地址。
服务器
服务器需要同时和多个客户端通信,每有一个客户端连接进来, 就启动一个新的服务器程序, 确保服务器程序和客户端是一对一的状态。
网卡的 MAC 模块将网络包从信号还原为数字信息,校验 FCS 并存入缓冲区。
网卡驱动会根据 MAC 头部判断协议类型,并将包交给相应的协议栈。
协议栈的 IP 模块会检查 IP 头部
(1) 判断是不是发给自己的;
(2) 判断网络包是否经过分片;(3) 将包转交给 TCP 模块或 UDP模块。如果收到的是发起连接的包,则 TCP 模块会
(1) 确认 TCP 头部的控制位 SYN;
(2) 检查接收方端口号;
(3) 为相应的等待连接套接字复制一个新的副本;
(4) 记录发送方 IP 地址和端口号等信息。收到数据包时,TCP 模块会
(1) 根据收到的包的发送方 IP 地址、发送方端口号、接收方 IP 地址、接收方端口号找到相对应的套接字;
(2) 将数据块拼合起来并保存在接收缓冲区中;
(3) 向客户端返回 ACK。
网络包的旅程