上周刚看完《网络是怎样连接的》这本书,这本书很适合作为网络的入门书,里面以一个“打开一个网页会发生什么事情”串了整个网络连接的过程。
基础流程
首先,先从上到下介绍了网络协议栈的一些基础知识。
-
应用层就是计算机里的应用程序
- HTTP协议常见命令为Get和Post
- 浏览器要解析URL,开头的http代表协议类型,www.xxx.com 为服务器域名,后面/dir/yyy.html为访问的文件名,如果只有路径会访问该路径下的默认文件default.index。
-
应用层会将数据跟端口号这些传给传输层比如TCP层。(端口号用来标记应用程序)
-
浏览器、邮件等应用程序收发数据一般用TCP,而DNS查询等收发较短的控制数据用UDP。
-
TCP是可靠的数据传输协议,对于数据需要进行响应以保证不丢失,有丢失重传、连续发送、滑动窗口等机制。
- TCP开始时先通过三次握手建立连接、交换各自的接受窗口大小以及初始化各自的发送序列号等。(1:SYC=1;2:SYN=1,ACK=1;3:ACK=1)
- 断开连接可由任意一方发起,但需要经历四次挥手。一方发起得到确认后,完成数据传输后另一方又发起得到确认(1:FIN=1;2:ACK=1;3:FIN=1;4:ACK=1)。套接字会等待2MSL再关闭,避免ACK包丢失造成的FIN重发而断开了可能建立的新连接。
- TCP收到数据后会先存放在内部的缓冲区,等数据长度接近MSS/达到一定时间后再发送出去。发送缓冲区的数据会以MSS长度为单位进行拆分,拆分出来的每块数据被放入单独的网络包。
- 网卡、集线器、路由器都没有错误补偿机制,一旦检测到错误就直接丢弃相应的包。由TCP层进行重传补救。TCP重发的等待时间根据ACK号的返回时间进行动态调整的。
- 通过滑动窗口机制连续发送,窗口大小的更新时机在接收方从缓存区取出数据并发给应用程序时。接收方在发送ACK号跟滑动窗口时会先等待一段时间,有可能合并其他通知一起发送。如多ack合为一个。
-
协议栈会将接收到的数据复制到应用程序的内存区,然后把执行权交给应用程序
-
这里文中还借助了socket库来解释连接跟发送的整个过程。(服务端:socket->listen->accept->recv->write->close,客户端:socket->connect->write->recv->close)
-
套接字对应了发送方跟接收方的IP地址跟端口,以及对应的应用程序。
-
-
接下来到IP层。在这里会涉及很多转发相关的协议介绍。
-
Ip地址是分配给网卡的,每个网卡对应一个IP地址。IP 模块根据路由表 Gateway 栏的内容判断应该把包发送给谁。
-
如何获取IP。——> DNS服务器。介绍了DNS服务器是如何工作的:按域名分级,从上到下。分配给根域DNS服务器在全世界只有13个IP地址,这些信息配置在DNS服务器程序的配置文件里。
-
介绍了IP地址的一些基本概念,默认网关、子网掩码、网络号跟主机号、内网跟外网。
-
在IP层必不可少的就是路由器。
- 路由器有一张IP协议的表,可根据这张表以及 IP 头部中记录的目的地信息查出接下来应该发往哪个路由器。在路由表找不到匹配路由会发到默认路由,如果默认路由设为0.0.0.0,那么就不会发生不知道转发到哪里的问题。
- 路由器每个端口带IP地址跟MAC地址。路由器的工作:生存时间-1,包分片,转发包,地址转换,包过滤。
- 根据路由协议机制,通过路由器之间的信息交换由路由器自行维护路由表的记录。各网络供应商可以通过交换的路由表只有自己的IP地址范围内可以进入高速通道。
- 规定一些地址只能用于内网(10.0.0.0 ~ 10.255.255.255、172.16.0.0 ~ 172.31.255.255、192.168.0.0 ~ 192.168.255.255),任何人可以自由使用,但是接入互联网时需要进行地址转换,改写IP地址跟端口号为公网地址。路由器维护了一张 公有地址&端口号 到 私有地址&端口号 的映射表。
-
-
IP层往下就是数据链路层(以太网协议)。这里传输的地址标识为MAC地址。每个网卡都有一个唯一的MAC地址标识。
-
如何获取发送方的MAC地址。——> ARP协议。发送方会向网络广播寻求某个IP地址对应的MAC地址,拿到对应地址后会写入本地缓存的MAC地址表里。
-
在这一层还介绍了交换机跟集线器。
- 集线器现在基本不怎么用了,它收到数据后会向所有端口广播发送数据,并且有冲突检测协议,只能有一条信号在链路中发送(CSMA/CD),为半双工。
- 交换机会记录每个端口对应的MAC地址表,只会往对应的MAC地址发送,当找不到/广播地址时会往除端口外所有端口发。如果发现一个包要发回到原端口时,就会直接丢弃这个包,以避免接收方重复接收。交换机可以同时转发多个包,为全双工。
- 路由器找不到该IP地址会发送ICMP信息返回消息不可达通知。
交换机跟路由器找不到地址操作不一样的原因:网络规模的大小。交换机连接的网络最多也就是几千台设备的规模,而路由器工作的网络环境就是互联网,它的规模是远远大于以太网的。
-
数据报里的MAC地址经由传输对象经常改变。但IP地址不会改变。
-
-
数据链路层往下就到了物理层,这里主要介绍了数字信号到电信号的转换。
-
网卡会将数据包转换为电信号发送出去,数字信号转换为电信号会涉及多路发送、降噪等内容。
-
PHY(MAU)模块会将信号转换为可在网线上传输的格式, 并通过网线发送出去。以太网规格中对不同的网线类型和速率以及其对应的信号格式进行了规定。目前网线基本都是双绞线的形式,主要就是为了抵消外部的电磁干扰。
-
多路发送主要就是通过频率/相位实现一条信号线能够叠加多个传输信号。
-
电信号随传输距离的增加衰减严重,而光纤不会。但只有一定角度的光信号进入光纤才能完成传输。现在基本都通过FTTH入户。
-
中断机制:网卡向扩展总线中的中断信号线发送信号,该信号线通过计算机中的中断控制器连接到 CPU。当 产生中断信号时,CPU 会暂时挂起正在处理的任务,切换到操作系统中的中断处理程序。然后,中断处理程序会调用网卡驱动,控制网卡执行相应的接收操作。
-
接收到一个包的流程?
-
信号的开头为报头,会根据报头的波形同步时钟,然后遇到起始帧分界符就开始将后面的信号转换为数字信号。PHY (MAU)模块会将信号转换成通用格式并发送给 MAC 模块,MAC 模块再从头开始将信号转换为数字信息,当到达信号的末尾时,还需要检查 FCS。FCS如果有问题会被当成错误包丢弃
-
FCS校验没问题的话,会检查MAC头部的接收方MAC地址跟自己的网卡MAC地址是否一致,不同的话会丢弃;一致则会放入缓存区。然后通过中断通知计算机应用程序。
-
网卡驱动被中断处理程序调用后,会从网卡的缓存区读取数据包,并通过MAC头部的以太网类型判断协议类型,然后交给不同的协议栈。若为TCP/IP协议,就交给TCP/IP协议栈。
-
IP模块首先检查IP头部的接受方地址,若不为自己的IP地址则返回ICMP消息把错误告诉对方。如果消息经过分片则需要还原为原始包,等待相同ID的包全部到达再进行分片重组。
-
TCP 模块会根据 IP 头部中的接收方和发送方 IP 地址,以及 TCP 头部中的接收方和发送方端口号来查找对应的套接字。然后根据套接字中的通信状态进行相应的操作。应用程序的话则将数据放入内存缓存区,连接/断开的控制包的话则返回相应的响应包。
What's more?
文中在每个部分还介绍了很多更为具体以及相关的一些知识。
网络运营商
电信号会传输到供应商的网络接入点,然后经由隧道传输。这里会涉及一些关于网络接入点的信号转换的知识。用户端路由器 D 发出的网络包通过 ADSL ModemE 和电话线到达电话局,然后到达 ADSL 的网络运营商(即 ISP,互联网服务提供商)。
- 互联网接入路由器会在网络包前面加上MAC头部、PPPoE头部、PPP头部总共3种头部, 然后发送给ADSL Modem。
- ADSL Modem会将包拆分成很多个信元(很小的数据块)。然后转换为电信号发送给分离器。
- 接收时,分离器在接收到混合了电话信号(低频)跟ADSL高频信号的混合信号时,需要对ADSL进行过滤再传给电话机,而ADSL Modem收到的为混合信号,内部过滤低频。
- 信号通过电话线到达电话局之后,会经过配线盘、分离器到达 DSLAM 。在这里,电信号会被还原成数字信息——信元。DSLAM 一般不用以太网接口,而是用 ATM 接口。
- 信元从 DSLAM 出来之后,会到达一个叫作 BAS 的包转发设备。BAS 和 DSLAM 一样,都具有 ATM 接口,可以接收 ATM 信元,还可以将接收到的 ATM 信元还原成原始的包。BAS会将收到的包前面的 MAC 头部和 PPPoE 头部丢弃,取出 PPP 头部以及后面的数据。BAS 会在包的前面 加上隧道专用头部 LSTP,并发送到隧道的出口。
- 网络包会到达隧道出口的隧道专用路由器,在这里隧道头部会被去掉,IP 包会被取出并被转发到互联网内部。
其他:用光纤来代替 ADSL 将用户端接入路由器和运营商的 BAS 连接起来 的接入方式就是 FTTH。用户端用光纤收发器/ONU(Optical Network Unit,光网络单元)转换信号。
ADSL 和 FTTH 接入网中,都需要先输入用户名和密码,登录之后才能访问互联网,而BAS就是登录操作的 窗口。 通过用户名和密码登录的步骤可以根据用户名来切换不同的运营商。
互联网接入路由器通过 PPPoE 的发现机制查询 BAS 的 MAC 地址(类似ARP,广播然后等消息)。BAS下发的TCP/IP参数会被配置到互联网接入路由器的 BAS 端的端口上,这样路由器就完成接入互联网的准备了。还有一种 DHCP 方式,它不使用 PPP,而是将以太网包直接转换成 ADSL 信号发送给 DSLAM。
网络包通过接入网之后,到达运营商 POP 的路由器。 NOC 是运营商的核心设备,从 POP 传来的网络包都会集中到这里, 并从这里被转发到离目的地更近的 POP,或者是转发到其他的运营商。
防火墙
防火墙主要通过包过滤方式去实现,可以通过发送方/接收方的IP地址、端口号、协议类型号、数据包标记位等实现数据包过滤。还可以借助代理做数据过滤。
通过防火墙没有对数据内容进行过滤,因此针对UDP这类没法做限制(一拦全拦),但是可以通过代理进行数据的过滤。比如公司内网对外网的代理服务器其实是可以获取到全部的数据报的,因此其实我们在公司内网看的数据就类似于“裸奔”。
负载均衡
-
负载均衡器可以定期采集 Web 服务器的 CPU、内存使用率,并根据 这些数据判断服务器的负载状况,也可以向 Web 服务器发送测试包,根据 响应所需的时间来判断负载状况。
- 在 HTTP 头部字段中添加一个 Via 字段,表示这个消息经过缓存服务器转发,然后将消息转发给 Web 服务器。
- 缓存服务器会添加一个 If-Modified-Since 头部字段并将请求转发给 Web 服务器,询问 Web 服务器用户请求的数据是否已经发生变化。
- Web 服务器会根据 If-Modified-Since 的值与服务器上的页面数据的最后更新时间进行比较,如果在指定时间内数据没有变化,就会返回表示没有变化的响应消息。否则,Web 服务器会返回最新版本的数据,然后缓存服务器加上 Via 字段发送给客户端,同时将数据保存在缓存中。
-
代理分为正向跟反向代理,正向代理是指在客户端上做代理,反向代理是在服务端上做代理,后者比较常用。
-
CDN集成了分布式、数据缓存跟负载均衡等能力,能够使用户从最近的服务器缓存上获取到想要的数据,提高网络传输速度。
- 首先,需要事先从缓存服务器部署地点的路由器收集路由信息。接下来,DNS 服务器根据路由表查询从本机到 DNS 查询消息的发送方,也就是客户端 DNS 服务器的路由信息。提供路由表的路由器位于缓存服务器的位置,而客户端 DNS 服务器也应该和客户端在同一位置,这样就等于估算出 了缓存服务器与客户端之间的距离,从而能够判断出哪台缓存服务器距离 客户端最近了。
- 我们可以在 DNS 服务器返回 Web 服务器 IP 地址时,对返回的内容进行一些加工,使其能够返回距离客户端最近的缓存服务器的 IP 地址 。
HTTP
书中还介绍了在TCP之上的应用层协议——HTTP协议。常用的HTTP指令为Get和Post,这里介绍了URL和URI,常见请求头以及HTTP数据包的格式,以及一些常见的响应码(1xx:连续传输;2xx:正常响应;3xx:重定向;4xx:客户端异常;5xx:服务器异常)
请求头里,Content-Type主要用于标识数据报里的数据类型,比如Image、Text、Video等。Content-Encoding用于标识编码格式,Location字段用于重定位。。在网页展示中,HTML为静态资源,文本跟图片需要分开为两次请求,请求的HTML文本里会包括图片的大小、位置跟URI,然后浏览器需要根据这个URI再去请求Web服务器去获取图片资源。CGI为动态程序。
双重IP校验以抵御在DNS在注册假域名的攻击。先根据域名在DNS上找到IP地址,再根据该IP地址去DNS反查域名看是否一致。
对于 HTML 文档、纯文本、图片这些基本数据类型,浏览器自身具有显示这些内容的 功能,因此由浏览器自身负责显示。
常见概念
头部信息
1. TCP头部:带端口号、控制位、ACK跟窗口等
2. UDP头部:带端口号
3. IP头部:带IP地址、分片信息
4. MAC地址:带MAC地址、协议类型
5. 网卡发送包:报头跟起始帧、FCS
6. 互联网接入路由器
常见缩写词
DNS:Domain Name System,域名服务系统。(存储域名跟IP地址的对照表)
MTU:Maximum Transmission Uinit, 最大传输单元。网络包的最大长度,以太网中一般为1500字节。
MSS:Maximum Segment Size,最大分段大小。为MTU-头部大小。为数据部分的大小。
ARP:Address Resolution Protocol,地址解析协议。用于查询IP地址对应的MAC地址
CSMA/CD
ICMP:Internet Control Message Protocol,TCP的一类控制消息。
CDN:Content Distribution Network,内容分发服务。
ADSL:Asymmetric Digital Subscriber Line,不对称数字用户线。
FTTH:Fiber To The Home,光纤到户。
DSLAM:DSL Access Multiplexer,数字用户线接入复用设备。它是一种电 话局用的多路 ADSL Modem
PPPoE:Point-to-Point Protocol over Ethernet,以太网的点对点协议。
POP:Point of Presense,中文一般叫作“接入点”。
NOC:Network Operation Center,网络运行中心。
DHCP:Dynamic Host Configuration Protocol,动态主机配置协议。
CGI:Common Gateway Interface,通用网关接口
常见问题
1. 为什么TCP的握手是三次,而挥手是四次?
详解:zhuanlan.zhihu.com/p/496244348
因为握手的时候并没有数据传输,所以服务端的 SYN 和 ACK 报文可以一起发送,但是挥手的时候有数据在传输,所以 ACK 和 FIN 报文不能同时发送,需要分两步,所以会比握手多一步。
三次握手是为了建立可靠的数据传输通道(双方都有发送+接收的能力),四次挥手则是为了保证等数据完成的被接收完再关闭连接。既然提到需要保证数据完整的传输完,那就需要保证双方都达到关闭连接的条件才能断开。
为什么客户端在第四次挥手后还会等待 2MSL?等待 2MSL 是因为保证服务端接收到了 ACK 报文,因为网络是复杂了,很有可能 ACK 报文丢失了,如果服务端没接收到 ACK 报文的话,会重新发送 FIN 报文,只有当客户端等待了 2MSL 都没有收到重发的 FIN 报文时就表示服务端是正常收到了 ACK 报文,那么这个时候客户端就可以关闭了。
2. UDP跟TCP的区别?各自的应用场景为?
- TCP需要先通过三次握手建立连接,然后通过ACK和丢失重传机制保证消息的可靠传输。一般在一些稳定的数据传输比如浏览器、邮件等需要用到。
- UDP不需要建立连接,只要知道对方的IP地址和端口号就可以发送数据,并且传输过程中接收方不需要回复ACK以保证接收。一般在实时性要求比较高如直播,以及数据较短的控制数据如DNS查询时用到。