type
status
date
slug
summary
tags
category
icon
password

1、计算机网络体系结构

在计算机网络中要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则。这些规则明确规定了所交换的数据的格式以及有关的同步问题。这些为进行网络中的数据交换而建立的规则、标准或约定称为网络协议(network protocol)。
通常我们不会使用一个网络模块去完成网络数据传输的所有工作,这样会导致网络模块过于庞大和复杂。我们会把网络模块进行分层划分,每一层只完成一部分工作内容,并向上层提供服务。计算机网络的各层及其协议的集合,称为网络的体系结构(architecture)。换种说法,计算机网络的体系结构就是这个计算机网络及其构件所应完成的功能的精确定义
分层时应注意使每一层的功能非常明确。若层数太少,就会使每一层的协议太复杂。但层数太多又会在描述和综合各层功能的系统工程任务时遇到较多的困难。通常各层所要完成的功能主要有以下一些(可以只包括一种,也可以包括多种):
  • 差错控制:使得和网络对等端的相应层次的通信更加可靠。
  • 流量控制:使得发送端的发送速率不要太快,要使接收端来得及接收。
  • 分段和重装:发送端把要发送的数据块划分为更小的单位,在接收端将其还原。
  • 复用和分用:发送端几个高层会话复用一条低层的连接,在接收端再进行分用。
  • 连接建立和释放:交换数据前先建立一条逻辑连接。数据传送结束后释放连接。
为了使不同体系结构的计算机网络都能互连,国际标准化组织ISO于1977年成立了专门机构研究该问题。不久,他们就提出一个试图使各种计算机在世界范围内互连成网的标准框架,即著名的开放系统互连基本参考模型OSI/RM (Open Systems Interconnection Reference Model),简称为OSI。一共有七层:
  • 应用层,负责给应用程序提供统一的接口
  • 表示层,负责把数据转换成兼容另一个系统能识别的格式
  • 会话层,负责建立、管理和终止表示层实体之间的通信会话
  • 传输层,负责端到端的数据传输
  • 网络层,负责数据的路由、转发、分片
  • 数据链路层,负责数据的封帧和差错检测,以及 MAC 寻址
  • 物理层,负责在物理网络中传输数据帧
由于 OSI 模型实在太复杂,提出的也只是概念理论上的分层,并没有提供具体的实现方案。事实上得到最广泛应用的不是法律上的国际标准 OSI,而是非国际标准TCP/IP。这样,TCP/IP就常被称为是事实上的国际标准。Linux 系统正是按照这套网络模型来实现网络协议栈的。一共有四层:
  • 应用层,负责向用户提供一组应用程序,比如 HTTP、DNS、FTP 等
  • 传输层,负责端到端的通信,比如 TCP、UDP 等
  • 网络层,负责网络包的封装、分片、路由、转发,比如 IP、ICMP 等
  • 网络接口层,负责网络包在物理网络中的传输,比如网络包的封帧、 MAC 寻址、差错检测,以及通过网卡传 输网络帧等
不过从实质上讲,TCP/IP只有最上面的三层,因为最下面的网络接口层基本上和一般的通信链路在功能上没有多大差别,对于计算机网络来说,这一层并没有什么特别新的具体内容。因此在学习计算机网络的原理时往往采取折中的办法,即综合OSI和TCP/IP的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚。
以上内容可以概括如下:
notion image

2、数据在网络协议栈的传输过程

以TCP/IP标准的五层协议作为例子,在TCP/IP网络模型里面,数据在每一层都会经过一次包装,每层的作用如下图所示:
网络协议层
作用
传输单位
应用层
体系结构中的最高层。应用层协议定义的是应用进程间通信和交互的规则。这里的进程(process)就是指主机中正在运行的程序。
报文(message)
传输层
负责为两个主机中的进程提供数据传输服务。主要在应用数据前面增加了 TCP 头。
报文段(segment)
网络层
负责为分组交换网上的不同主机提供数据传输服务。 主要在 TCP 数据包前面增加了 IP 头。
分组或包(packet)
链路层
负责为物理链路上两个相邻结点之间提供数据传输服务。主要在 IP 数据包前后分别增加了帧头和帧尾。
帧(frame)
物理层
在物理层上所传数据的单位是比特。发送方发送1(或0)时,接收方应当收到1(或0)而不是0(或1)。
比特(bit)
notion image
应用进程的数据在各层之间的传递过程中所经历的变化如下图所示。这里为简单起见,假定两台主机通过一台路由器连接起来。
notion image
可以用一个简单例子来比喻上述过程。有一封信从最高层向下传。每经过一层就包上一个新的信封,写上必要的、交由下一层处理的地址信息。包有多个信封的信件传送到目的站后,从第1层起,每层拆开一个信封后(即按协议进行处理后)就把信封中的信交给它的上一层。传到最高层后,取出发信人所发的信交给收信人。
虽然应用进程数据要经过如图1-19所示的复杂过程才能送到终点的应用进程,但这些复杂过程对用户来说,却都被屏蔽掉了,以致应用进程AP1 觉得好像是直接把数据交给了应用进程AP2。同理,任何两个同样的层次(例如在两个系统的第4层)之间,也好像如同图1-19中的水平虚线所示的那样,把数据(即数据单元加上控制信息)通过水平虚线直接传递给对方。这就是所谓的“对等层”(peer layers)之间的通信。我们以前经常提到的各层协议,实际上就是在各个对等层之间传递数据时的各项规定。

3、网络协议栈的具体实现协议

notion image

4、Linux系统收发网络

notion image

Linux接收网络包的过程

如果每当网卡收到一个网络包,就触发一个中断告诉操作系统,会造成cpu频繁中断。Linux 内核在 2.6 版本中引入了 NAPI 机制,它是混合「中断和轮询」的 方式来接收网络包,它的核心概念就是不采用中断的方式读取数据,而是首先采用中断唤醒数据接收的服务程序, 然后 poll 的方法来轮询数据。
  1. 当有网络包到达时,通过 DMA 技术,将网络包放入到 Ring Buffer,触发中断。
  1. 网卡发起硬件中断,于是会执行网卡硬件中断处理函数,中断处理函数处理完需要「暂时屏蔽中断」,然后唤醒「软中断」来轮询处理数据,直到没有新数据时才恢复中断。
  1. 「软中断」从 Ring Buffer 中拷⻉数据到内核 struct sk_buff 缓冲区,作为一个网络包交给网络协议栈进行逐层处理。
  1. 进入网络接口层,在这一层会检查报文的合法性,如果不合法则丢弃,合法则会找出该网络包的上层协议的类型,比如是 IPv4,还是 IPv6,接着再去掉帧头和帧尾,然后交给网络层。
  1. 进入网络层,则取出 IP 包,判断网络包下一步的走向,比如是交给上层处理还是转发出去。当确认这个网络包要发送给本机后,就会从 IP 头里看看上一层协议的类型是 TCP 还是 UDP,接着去掉 IP 头,然后交给传输层。
  1. 进入传输层,取出 TCP 头或 UDP 头,根据四元组「源 IP、源端口、目的 IP、目的端口」 作为标识,找出对应的Socket,并把数据拷⻉到 Socket 的接收缓冲区。
  1. 进入应用层,应用层程序调用 Socket 接口,从内核的 Socket 接收缓冲区读取新到来的数据到应用层。

Linux发送网络包的过程

发送网络包的流程正好和接收流程相反:
  1. 首先,应用程序会调用 Socket 发送数据包的接口,由于这个是系统调用,所以会从用户态陷入到内核态中的 Socket 层,Socket 层会将应用层数据拷⻉到 Socket 发送缓冲区中。然后网络协议栈从 Socket 发送缓冲区中取出数据包,并按照 TCP/IP 协议栈从上到下逐层处理。
  1. 进入传输层,如果使用的是 TCP 传输协议发送数据,那么会在传输层增加 TCP 包头。
  1. 进入网络层,网络层会给数据包增加 IP 包,然后通过查询路由表确认下一跳的 IP,并按照 MTU 大小进行分片。
  1. 进入网络接口层,过 ARP 协议获得下一跳的 MAC 地址,然后增加帧头和帧尾,放到发包队列中。
  1. 触发软中断告诉网卡驱动程序,这里有新的网络包需要发送,最后驱动程序通过 DMA,从发 包队列中读取网络包,将其放入到硬件网卡的队列中,随后物理网卡再将它发送出去。
 
计算机网络系列(二):应用层(HTTP)Docker系列:安装常用软件