读书笔记——《网络是怎样连接的》


banner

这是一本从计算机类图书畅销榜中随手挑出来读的书。原本并没有很高的期望,但读完之后意外的觉得还挺不错。在客户端应用开发工作中,端侧的网络状况分析处理是一个无法回避的难题。通过编程语言本身及其相关类库提供给我们的网络错误信息——例如 Timeout, NotFound, SocketTimeout 等等,我们往往只能在用户交互层面简单的处理为“网络异常”,但这对用户来说基本没有帮助,而我们往往也缺乏能更进一步分析异常根因的方式方法。阅读这本书,了解网络连接的各个环节,也许能有更多的分析网络问题的思路和方法。

book-overall

客户端程序

在客户端程序中,向请求向服务端获取数据非常简单。在这简单的操作之下,框架帮我们封装了更多的细节。其大致流程如下:

  • 解析 URL:从请求参数中提取 http 协议所需要的各个部分,包括域名、资源路径、请求方法等。
  • 解析域名:将服务器名转换成 IP 地址。TCP/IP 网络是通过 IP 地址来确定通信对象的,不知道 IP 地址就无法将消息发送给对方。域名解析服务(DNS Server)提供了域名到 IP 或 IP 到域名的查询。当然,要使用它,先得需要知到这个域名解析服务器的地址(系统连网后通常就会自动设置好,即 DHCP),也可以手动指定);另外,作为一个服务器,它也会有数据不全(按一定规则找上级 DNS 服务器接力查询)、查询慢(具有内存缓存机制)、缓存失效(可手动清缓存)等问题。操作系统层面已提供了使用接口及程序封装(例如 getAddrInfonslookupdig 等),可用来分析相关问题。dns lookup
  • 发送数据:建立 Socket 通信管道,组装并发送 http 报文等。这部分通过向操作系统内部的协议栈发出委托实现。

协议栈、网卡

操作系统通过协议栈(即网络控制软件)和网络硬件(即网卡)将数据发送给服务器。一些有趣的概念:

  • Socket 本质上只是一个用于存放控制信息的数据结构内存空间。它记录了通信过程的控制信息,例如通信对象的 IP 地址、端口号、通信操作的进行状态等。它只是一个概念,并没有一个真的“连接”的实体存在。所谓的“连接”,本质就是客户端和服务端各自开辟一块对应的 Socket 数据结构内存空间,并进行控制信息的交换。可以使用 netstat 命令显示当前系统中所有的 Socket 列表。
  • 在连接过程中进行数据收发操作时,需要一个用来临时存放要收发数据的内存空间。这块内存空间被称为缓冲区。通过控制缓冲区大小,可以调节带宽利用率和响应速度。
  • 协议栈中,IP 模块负责完成包的收发操作。它接收 TCP 模块的委托,生成 IP 头部,并附加在 TCP 头部。IP 头部中需要填写发送方的 IP 地址,即“计算机的 IP 地址”,但严格来说这个说法不准确。计算机上如果有多个网卡时,每个网卡都会有自己的 IP 地址,此时计算机就有了多个 IP 地址,因此在组装 IP 包时,协议栈需要判断应该使用哪个网卡来发送这个包。可以通过 route 查看系统的路由表配置:route print

集线器、交换机、路由器

从计算机网卡发出来的网络包会通过集线器、交换机或路由器等设备转发,进入互联网,并最终到达目的地。一些有趣的概念:

  • 网络包通过相应网卡的物理层装置转换为正负变化的电压组成的电信号,进入网线中传输。如果周边存在电磁波干扰(主机、显示器、周边的荧光灯等都有可能),信号传输过程会发生失真,进一步造成通信数据中 0/1 的误判,并发生包内容差错。在应用侧,这会表现为网络丢包率、延迟变高。可以采用更高标准的网线(例如五类网线换七类)以减少外部串扰、提高传输性能。
  • 交换机收到包后,按 MAC 地址表查找目标设备,并将包发送到相应的端口。MAC 地址和交换机的端口一一对应,当计算机设备连接上交换机时,交换机会根据其发过来的包更新 MAC 地址表。但如果设备移动了,还把包往原本的端口发,就会产生通信失败。为了解决这个问题,交换机中的 MAC 地址表中的记录不能永久有效,而是要在一段时间不使用后自动删除(一般为几分钟)。因此,有时我们可能的确需要重启一下交换机以清除其 MAC 地址表缓存。
  • 路由器收到了来自集线器和交换机的网络包,并负责将其转发给下一个路由器。类似的,它也是通过查表来决定转发目标,但这个表是 IP 地址表而不是 MAC 地址表。这个表的维护可以手工控制,也可以由路由之间的信息交换协议自行维护。但整个互联网是如此庞大,不可能把所有的可转发目标都配置在每个路由器中,因此往往只需要配置一个子网掩码为 0.0.0.0 的默认网关地址,就可以将所有的未识别流量转发到该网关,由它进行下一轮转发。每一轮转发,IP 包头部的 TTL 会相应的递减一;当这个值减到 0 时,包即会被丢弃。这是为了防止包在多个路由之间转移时产生死循环。

接入网、网络运营商

所谓接入网,就是连接互联网与家庭、公司网络的通信线路,例如以前用的 电话线、ADSL、ISDN 等;公司里还可能有使用专线。网络包通过接入网后,到达互联网的内部,即运营商网络。一些有趣的概念:

  • ADSL 使用间隔为 4.3125kHz 的上百个不同频率的波进行合成,每个波都采用正交振幅调制(通信专业的同学应该会比较熟悉),即利用波的振幅和相位的组合正交使得每个波表示更多的比特数,从而提高传输效率:QAM
  • 互联网的实体并不是由一个组织运营管理的单一网络,而是由多个运营商网络互相连接组成。运营商本质上也是一种高性能路由设备组成的网络。他们有的有自己的专属光纤光缆实现特定节点之间的高速网络(比如一条中美之间直通的高速线路),有的干脆从其他线路服务商进行线路租借。不同的运营商的路由器的之间交换彼此掌握的路由表信息,从而实现彼此互联。当然,这个过程并不是完全透明对等,还需要考虑线路是否可被共享的问题,否则辛辛苦苦自建的高速线路就成义务劳动了。

总结

尽管每天的工作和娱乐都在和互联网打交道,受限于个人的专业和经验,实际上还是很少有人能说清楚的清楚网络链路上每个部分的框架结构。阅读这本书,不仅能结合实际了解现状,也能在不同的角度去思考计算机网络的设计思路和方法,颇有一种技术方案评审的思辨感。另外,后续如果想进一步实践分析网络情况的方法,也可以参阅《Wireshark网络分析的艺术》等书籍。

References