《网络是怎样连接的》学习总结

前言

这本书从一个比较宏观的视角,解释了一个网络包从发送到接收的全过程,虽然此前也学过《计算机网络》,但《计算机网络》对每个细节解释的更加详尽,在学习时容易迷失在具体的细节里,觉得枯燥无味,对理论知识也难以联系到实际。

所以我觉得本书适合作为计算机网络的入门书籍,从宏观的角度对网络有一个直观的了解,对于具体某个环节的细节,再去查阅其他更详细的书籍。

第一章:Web 浏览器

浏览器通过 HTTP 报文向服务器发出请求,期待服务器作出某种响应。服务器会对所接受的请求进行反馈,让浏览器获得请求所产生的结果。

IP 地址通过 DNS 服务器来查询

通过 Socket 库中的 API 向 DNS 服务器发出域名解析请求(API 会将操作委托给操作系统的协议栈),然后 DNS 服务器返回请求者一个对应的请求结果,通过域名查询 IP 地址,网络的进行最终还是基于 IP 地址。

DNS 服务器的 IP 查询

从顶级域名向次级域名依照层级查询

委托协议栈发送信息

数据收发依靠协议栈,协议栈会使用套接字建立通信信道,在信道内收发信息

  • 创建套接字:每个套接字都有自己的标识符
  • 连接管道:通过 IP 地址和端口,找到对方的套接字,从而建立连接
  • 传递信息
  • 断开连接:会向对方发送通知

第二章:协议栈和网卡

数据传输流程

TCP 协议的数据传输流程:

  1. 创建套接字
  2. 连接服务器
  3. 收发数据:
    • IP 与 以太网的包收发操作
  4. 断开连接并删除套接字

UDP 协议的数据传输流程:

  1. UDP 协议的收发操作

创建套接字

套接字由应用程序调用 Socket 库进行创建,而 Socket 库又会调用操作系统的协议栈进行创建,所以实际上套接字的创建是由操作系统的协议栈完成的。

套接字本质上就是一些控制信息,他的内容包含:

  • 通信协议:例如 TCP 或 UDP
  • 发送方的信息:自己的 IP 地址和端口号
  • 接受方的信息:对方 IP 地址和端口号
  • 通信状态:等待连接、正在通信等等
  • PID:套接字所对应程序的进程标识符

创建套接字时,其控制信息是不完全的,需要连接服务器这一个步骤进一步填充控制信息。例如服务器是不知道客户端的 IP 地址的,他需要客户端的请求才能完善控制信息。

连接服务器

连接是一个高层宏观上的抽象形容,在实际的网络链路中,并没有一个连接产生。

1

TCP 头部:服务器和客户端进行信息交换的控制信息,他的作用是让通信双方知道对方是谁(应用程序级别上的谁,没有 IP 地址信息),以及数据的情况。

连接服务器实际上的操作是一个叫做三次「握手」的 TCP 头部信息交换,这个操作的作用就是让通信双方,知道对方是谁,同时互相确认对方已经知道我是谁。

TCP 头部是由操作系统协议栈完成的,应用程序是感知不到的,对应用程序来说,TCP 头部是不存在的,在应用程序中,知道套接字就足够了。

收发数据

在收发数据中,过大的包(数据)需要切分

使用 ACK 号确认包已收到,通常是滑动窗口下的 ACK 号,确认该 ACK 号之前的包都已收到。

断开连接

断开连接实际上的操作是一个叫做四次「挥手」的 TCP 头部信息交换

在 TCP 连接断开之后,套接字也会在一段时间过后删除。

IP 与以太网的收发操作

实际传输过程中,数据包会经过许多转发设备,他们负责把数据送往该去的地方。

MAC 头部和 IP 头部就负责决定送往哪一个转发设备。

2

IP 头部:在网络中传输的控制信息,报文发给谁(目的 IP 地址,这里是最终的目的 IP 地址),生存时间等等。

3

MAC 头部:在网络中传输的控制信息,报文下一跳发给谁,在传输的过程中都会在变。

IP 协议:判断下一个 IP 转发设备(路由器)的位置(在实际传输前,需要知道对方的 MAC 地址)

ARP 协议:获取下一个转发设备的 MAC 地址

MAC 地址:负责将包传输给下一个转发设备(在不同的网络中,例如无线网,就不用 MAC 地址,可能使用不同的头部,但总之他的任务是将包传输给下一个转发设备)

当路由器收到包时,MAC 头部会被丢弃,因为其实际上指向自己,然后加上下一跳的 MAC 地址再发送。

UDP 协议

不需要连接,也没有确认机制

4

UDP 头部:只有双方端口号、数据长度和校验和四个字段

第三章:转发设备

集线器

集线器的一个端口接收到信号后,会广播至所有其他端口,虽然属于转发设备,其实可以理解成导线,他只是将信号扩散到所有线路。

所以集线器所连接的网络,会发生信号碰撞,不能够支持全双工通信,同时只能发送信号或接收信号。

交换机

交换机转发表:

目标 MAC 地址 转发端口 其他信息
00-60-97-A5-43-3C 2
00-00-C0-16-AE-FD 7

交换机通过 MAC 头部信息,根据内部转发表将包转发到特定的端口上。所以隔离了冲突域,网络内不会产生信号碰撞,可以进行全双工通信,即网络内部可以同时进行信号的发送和接收。具体表现为某条线路进行信号的发送,另一条线路进行信号的接收,互不影响。

交换机会检测包的校验信息,如果包产生错误,则会丢弃。

交换机可以同时转发多个包,发布到不同的端口上,相比集线器效率更高。

自动协商:当没有信号传输时,信道会被默认信号填充,其包含了双方所支持的工作模式(全双工、半双工)及相关信息,交换机和计算机就可以据此选择一种双方都支持的传输方式。

交换机内部转发表的维护

  1. 收到一个包时,会将发送方的 MAC 地址及其输入端口写入转发表中,即记录下这个包发送者的信息。
  2. 由于网络内的设备可能发生改变,所以转发表需要维护有效性,对于一些失效的信息,要删去,所以转发表内的条目,在一段时间不使用之后就会被删除。

特殊情况

  1. 转发表内没有目标 MAC 地址相对于的条目,不知道这个包该往哪个端口发送,这时就会进行广播,将包发送到所有其他端口上(不包括包传进来的那个端口)
  2. 如果目标端口是源端口(包传进来的端口),则不会进行转发,即不会把自己发出去的包传回给自己。

路由器

路由器路由表:

目标地址 子网掩码 网关 接口 跃点数
10.10.1.0 255.255.255.0 ———— e2 1
10.10.1.101 255.255.255.255 ———— e2 1
192.168.1.0 255.255.255.0 ———— e3 1
0.0.0.0 0.0.0.0 192.0.2.1 e1 1

路由器根据 IP 头部信息,根据内部转发表将包转发到特定的 IP 设备上(计算机或路由器),实际上也就是根据 IP 信息将包转发到路由器的特定端口上(路由器的各个端口具有独立的 MAC 地址和 IP 地址),然后端口会将包传输的任务交给交换机或集线器,让他们完成具体的传输工作。

路由器接收到包之后,会检查 MAC 地址是否与自身的匹配,不匹配则丢弃,和计算机是一样的。

路由聚合:将多个子网合并成一个子网,简化路由表。反过来也成立,将一个子网中的网络单独拿出来作为一个路由表项,可以优先匹配发往这个子网。

路由表的维护:使用例如 RIP、OSPC、BGP 等路由协议对路由表进行维护。

包的有效期:在路由中可能产生回路,导致包不断在回路中转发,浪费网络资源,所以当包被转发一定次数之后就会被丢弃。

包的分片:路由器可以将大包进行分片,拆分成小包,以满足各种不同的网络条件。在分片过程中会修改 IP 头部的相关信息(可能还会修改 MAC 头部)

ARP 协议:由于路由器根据 IP 地址进行转发,但实际传输工作基于 MAC 地址,所以没有对方的 MAC 地址,实际的传输就无法完成。路由器会使用 ARP 协议查询对应 IP 地址的 MAC 地址。

转发规则

  1. 对 IP 地址进行匹配,只会匹配网络号,忽略主机号。子网掩码越长的匹配越优先,例如上表中的第一行和第二行,对于一个 IP 10.10.1.101 的匹配都是符合的,但第二行的子网掩码更长,所以优先级更高,匹配第二行。
  2. 默认路由:例如上表最后一行,子网掩码为 0.0.0.0 意味着需要匹配的网络号位数为 0,当其他所有匹配都不成立之后,使用这个表项(子网掩码最短,优先级最低)
  3. 如果没有匹配的结果,则通过 ICMP 通知发送方。

地址转换功能

由于 IP 数量有限,规定内网的私有 IP 地址可以重复(例如 192.168.x.x,许多局域网都是使用这种 IP 地址)。

地址转换实际上就对 IP 地址和端口进行改写,对外采用公网公有 IP 地址(公有不会重复),对内采用私有 IP 地址。包经过路由器传往公网时,地址会被改写为公网的 IP 地址,而公网的包传往内网时,地址会被改写为内网的 IP 地址(这基于路由器的各个端口有不同的 IP 地址和 MAC 地址)

地址转换表示例:内网的不同地址,被映射到同一个公网地址,用端口号加以区分

公有地址(外网) 端口号 私有地址(内网) 端口号
198.18.8.31 5436 10.10.1.1 1025
198.18.8.31 5437 10.10.1.2 1025
198.18.8.31 5438 10.10.1.3 2538

内网访问外网,即使路由器中的地址转换表没有对应的表项,此时只需要生成一个新的即可(没被使用的新端口号),而外网访问内网,如果没有对应的表项,路由器也不知道该转发给谁,此时就只能丢弃,在这个意义上,地址转换功能提高了内网的安全性,能够阻断外界的非法访问。

三者总结

集线器和交换机都没有 MAC 地址和 IP 地址,他们不能作为信号的终端,只能作为传输信号的中介,而路由器和计算机具有 IP 地址和 MAC 地址,他们可以作为信号的终端。

换句话说,我可以将包发到目标计算机或路由器上,但不能说将包发到目标交换机或集线器上,他们即使拿到包,也只会转发,不会保存。所以说发到是没有意义的,只能说经过。

第四章:互联网内部

对于大部分个人或商用的网络,都属于互联网边缘,而运营商及其内部的网络,属于互联网内部。大部分的网络信息,都是从互联网边缘的设备开始,经过互联网内部,从而达到另一个互联网边缘的设备。

BAS 宽带接入服务器

用户数据从家中或公司中传出,接着会传入 BAS 中,这里会进行一个用户认证的过程,例如输入用户密码,确认用户是可上网的状态。

完成认证之后,认证服务器会下发 TCP/IP 配置信息(IP 地址等等),让用户具有公网 IP,才能实现上网功能。

DHCP 动态配置

通常用于局域网内的私有 IP 配置,设备向路由器发出请求,给本机配置一个 IP 地址,DHCP 会自动采用一个未被使用的 IP 地址配置给该设备,这样就不用手动在路由器中设置 IP 地址等相关信息了。

例如 WIFI 路由器,连接时并不需要手动配置 IP 地址就能上网,就是使用了 DHCP 动态配置。

POP 和 NOC

互联网的实体是由多个运营商网络相互连接组成的,这些与用户进行连接的设备就叫做 POP(Point of Presense 接入点),是互联网实体的入口,数据经过 POP 之后就真正进入了互联网的内部。

NOC(Network Operation Center 网络运行中心)是运营商的核心设备,从 POP 传来的数据都会汇集到这里,然后转发给下一个 POP 或运营商,它具有非常高的数据吞吐量。

IX(Internet eXchange 互联网交换中心),数据汇集到这里,集中对数据交换进行管理,IX 的实体实际上就是高性能的交换机。

5

互联网内部的转发

运营商中设备对数据转发也需要转发表,但一个运营商显然不可能掌握整个互联网的信息,所以运营商间还需要相互交换路由信息,来更新自己的转发表。

另外,由于运营商是个盈利性质的组织,其转发规则更加复杂,最终所转发的线路并不一定是最快的,这里面还有一些优先级相关的规则。

第五章:服务器局域网

Web 服务器的部署

  1. 直接部署在服务端的局域网内,对外暴露一个公有 IP 地址,让外部进行访问。通过防火墙对非法的流量进行阻断,以及隔离公司内网和公共区域。从外部不允许访问公司内网,但可以访问到公共区域内的 Web 服务器。
  2. 部署在数据中心,数据中心通常位于运营商的网络内部,具有较快的速度,也有更高的安全性。

防火墙

包过滤方式:
只有满足对应规则的包才能通过防火墙,否则丢弃。包过滤不会查看包的数据部分,会通过 IP 头部、TCP 头部等等信息来进行判断。

过滤目标:例如要禁止服务器主动访问外部网络(阻止某些病毒传播),但同时又要允许客户端能够访问服务器,还要服务器能和客户端进行正常信息交流。

过滤规则:假设 Web 服务器的 IP 地址为 192.0.2.0/24,程序端口为 80

05-1

这是一个简单的防火墙包过滤的例子:

  1. 第一行代表允许接受方为本机且端口号为 80 的包通过防火墙
  2. 第二行代表拒绝发送方为本机、端口号为 80 且是向外主动进行 TCP 连接的包通过防火墙(在 TCP 连接的过程中,服务器需要向外发送包,所以我们不能完全阻止向外发送的包,否则和客户端正常的信息交流都完成不了。但可以通过 TCP 控制位判断出主动连接,从而阻止服务器主动对外建立 TCP 连接)
  3. 第三行代表除了主动建立 TCP 连接,其他向外发送的包都是允许的(限定了端口号),这里也就是和客户端进行正常的信息交流
  4. 其他情况则一律阻止

一般来说 80 端口号是 HTTP 应用默认的端口号,所以以上的过滤规则,只允许 HTTP 应用的信息交流,其他应用一律都被阻止了,如果还需要对外提供其他功能,还需要单独设置其他端口号的过滤规则。

防火墙只能根据头部信息决定包是否通过,对于数据部分的攻击无法防范,而这部分实际上属于程序漏洞范畴,这部分的攻击是难以防范的。

负载均衡

当访问量非常大时,单台服务器的性能和带宽是有限的,此时只能通过增加服务器数量来分担负载。

DNS 轮询:一个域名可以注册多个 IP 地址,此时 DNS 服务器返回 IP 地址时会循环返回,例如有三个 IP 地址,第一次返回第一个,第二次返回第二个,第三次返回第三个,第四次会再次返回第一个,这样就完成了一个简单的负载均衡,将请求流量均匀的分配给三台服务器。

但 DNS 轮询规则过于简单,在一些复杂的场景下难以胜任。而且无法支持一些需要持续连接的应用,例如当前操作访问第一个服务器,数据保存在第一个服务器上,下一次操作访问第二个服务器,这时候就找不到之前的数据了。

负载均衡器:代替 Web 服务器注册到 DNS 服务器中,所有请求都经过负载均衡器,由负载均衡器决定该请求转发给哪一个服务器。
此时就可以编写一些程序,实现一些复杂的条件判断,负载均衡器还可以查询 Web 服务器的情况,判断服务器压力,从而决定将请求转发给哪个服务器。
也就可以实现持续连接的操作,通过包的信息,指定这些需要持续连接的包只发给同一个服务器。

05-2

缓存服务器

另一种减轻 Web 服务器负载的方法是设立缓存服务器,他同样会代替 Web 服务器注册到 DNS 服务器中,客户端只能访问到缓存服务器。

05-3

对于一个请求,缓存服务器会查看本机中是否有该资源,如果有则直接响应,没有再向 Web 服务器请求,这样就减轻了 Web 服务器的负担。

资源具有时效性,需要确认该资源是否是最新的,有两种方式:

  1. 主动询问,当存在该资源时,主动向 Web 服务器发出询问,对比是否是最新的(对比的是某种摘要信息,和源资源相比小很多),如果不是则再向 Web 服务器请求资源,拿到最新的。
  2. 被动更新,当资源发生更新时,Web 服务器会主动通知缓存服务器,进行资源的更新。

正向代理

客户端一侧的代理服务器,也具有缓存功能,正向代理会代替客户端向服务器发出请求,通常用于防火墙内的设备进行互联网访问。

客户端发出请求时,请求会到达代理服务器,代理服务器随后修改相关信息,然后转发请求,所以服务器只会看到代理服务器,代理服务器代替了客户端进行请求,使得真实客户端对服务器不可见。

但使用正向代理时,需要手动设置代理服务器的 IP 地址,错误设置会导致网络功能异常,所以比较麻烦。

反向代理

服务端一侧的代理服务器,和正向代理相反,代替服务端和客户端进行交流。

客户端发出请求会到达(反向)代理服务器,代理服务器随后查询相关的 Web 服务器获得资源,然后代替 Web 服务器向客户端响应请求,这样客户端只能看到代理服务器,从而使真实服务器对客户端不可见,提高了服务器的安全性。

同时客户端也不需要进行额外的设置,只需要服务器进行一次反向代理的设置即可。

透明代理

透明,顾名思义,双方都察觉不到透明代理的存在,就相当于是一个导线,不过有一些额外的功能。

由于透明的特性,客户端和服务端都不能对他进行配置,所以透明代理通常是放在链路中,拦截所有请求。

可以充当一个缓存服务器、网关或防火墙。例如在公司内网,透明代理可以作为一个访问外网的控制网关,只会转发允许的请求,拦截非法的请求;或者记录用户网络行为,跟踪用户的网络数据。

内容分发服务

缓存服务器设置在服务端时,可以减少 Web 服务器的流量,但无法减少互联网的流量,设置在客户端则可以。不过问题在于,客户端的缓存服务器,服务端无法进行管理,甚至客户端是否采用缓存服务器都不可知。

内容分发服务就是同时减少 Web 服务器流量和互联网流量,尽可能使缓存服务器靠近客户端,同时服务端又能够对其进行管理。

内容分发服务运营商会在互联网中部署很多的缓存服务器,关键的问题在于,客户端如何才能够找到最近的缓存服务器,从而实现上述的两个减少。

05-4

  1. 采集缓存服务器的路由表,集中到服务端的 DNS 服务器中,然后根据路由表等相关信息,查询到客户端 DNS 服务器的距离,以此作为一个距离的估算,从而决定返回哪一个缓存服务器的 IP 地址。这样的方式精度不高。

05-5

  1. 基于重定向,在重定向服务器中集中路由表,但此时发送方是客户端,根据客户端的 IP 地址进行估算可以得到更准确的精度,然后再决定使用哪一个缓存服务器,采用重定向的方式让客户端访问这个缓存服务器。

第六章:服务器内部

服务器程序结构

  • 等待连接模块:当程序完成初始化工作之后,就会启动等待连接模块(启动套接字,等待连接),当客户端请求连接时,将连接的套接字移交给通信模块
  • 通信模块:与客户端进行通信,每个套接字都会创建一个新的通信模块

套接字生命周期

  1. 创建套接字,设置为等待状态:socket()
  2. 等待连接,接受连接:bind()listen()accept()
  3. 收发数据:read()write()
  4. 断开连接并删除:close()

在接受连接的过程中,会生成一个套接字的副本,准备可能的下一个连接,如果不生成副本,套接字用完就无法连接了。

套接字的匹配需要:客户端 IP、端口号,服务端 IP、端口号

IP 模块的接收操作

先查看 IP 头部,确认接受方是自己,然后检查 IP 包是否有分片,如果有分片,暂存至缓存区,等所有分片到达后,组成原始包,然后根据头部协议字段,上交给上层(TCP 或 UDP 模块)

TCP 模块的连接

  • 确认 TCP 头部的控制位 SYN
  • 检查接收方端口号
  • 为相应的等待套接字创建副本
  • 记录发送方 IP、端口号等信息

TCP 模块的接收

  • 根据包信息找到对应的套接字
  • 将数据存至缓存区
  • 向客户端返回 ACK

Web 服务器程序

URI 所对应的目录并不一定是服务器中的实际目录,为了安全等需要,Web 服务器程序有一个虚拟目录,与实际目录有一个映射关系。

当 URI 请求的是一个 HTML 文档或图片等静态资源,直接返回文件即可,当 URI 请求的是动态资源时,就会调用 CGI 程序。

服务器会运行 URI 所指定的程序,并将相应的参数递交给他,处理结果会返回至 Web 服务器,然后 Web 服务器对客户端进行相应。

Web 服务器的访问控制

  • 根据客户端 IP 地址
  • 根据客户端域名(根据客户端 IP 地址反查域名)
  • 根据用户名和密码
上一篇 下一篇

评论 | 0条评论