小土刀

【不周山之计算机基础】计算机网络协议指南

如果说计算机科学中最重要的概念是抽象,那么『分层』绝对有资格争榜眼,再不济也是一个探花。计算机网络是最能代表『分层』思想的概念,本文我们就来了解一下计算机网络中的各种协议。


更新历史

  • 2016.12.03: 完成初稿

系列目录

任务目标

  1. 了解计算机网络的几种分层模型
  2. 了解数据链路层、网络层、传输层和应用层的常见协议及其特性
  3. 学会利用命令查看基本的网络信息

分层模型

网络通信是基于分层模型的。虽然不同的协议有不同的层级划分(甚至同一种协议也有不同的层级划分),但是都离不开分层。分层的好处有很多,最重要的是能够比较好控制具体实现的复杂度,由于每层之间由事先约定的接口通信,并不需要关心其他层的实现细节。

比较出名的分层模型有 OSI 分层模型TCP/IP 分层模型,本文以 TCP/IP 的四层模型进行讲解,他们分别是:

  • 网络接口层(link layer): 以太网, Wi-Fi
  • 网络互连层(internet layer): IP, ARP
  • 传输层(transport layer): TCP, UDP, RTP, SCTP
  • 应用层(application layer): HTTP, FTP, DNS

下面就开始分别介绍这四层的基本概念和重要的协议。

网络接口层

网络接口层的基础是光纤、电缆或者电磁波等真实存在的物理媒介。对于数字应用来说,我们只需要两种物理信号来分别表示 0 和 1,比如用高电压表示 1,低电压表示 0,就构成了简单的物理层协议。针对某种媒介,电脑可以有相应的接口,用来接收物理信号,并解读成为 0/1 序列

在这些介质中,信息以『帧(frame)』为单位传输。所谓的帧,是一段有限的 0/1 序列。连接层协议的功能就是识别 0/1 序列中所包含的帧。比如说,根据一定的 0/1 组合识别出帧的起始和结束。在帧中,有收信地址(Source, SRC)和送信地址(Destination, DST),还有能够探测错误的校验序列(Frame Check Sequence)。当然,帧中最重要的最重要是所要传输的数据(payload)。这些数据往往符合更高层协议,供网络的上层使用。与数据相配套,帧中也有数据的类型(Type)信息。连接层协议不关心数据中到底包含什么。帧就像是一个信封,把数据包裹起来。

深入理解帧(Frame)

帧的结构很简单,一共三部分:头部 | 数据(Payload) | 尾部,发送时由头发送到尾,其中:

  • 头部: DST SRC Type
  • 数据: Payload(Data)
  • 尾部: Pad FCS Extension

更正:PreambleSFD 如上图所示是 packet 的一部分,具体参考 这里

我知道看到这些奇奇怪怪的单词大家一定一头雾水,不要紧张,这就来一个一个解释:

  • Preamble: 翻译过来叫序言,是一帧的前 7 个字节,每个字节都是 10101010,所以合起来大概样子是 10101010101010101010101010101010101010101010101010101010。这是要干嘛?对表!为什么要对表!因为不同的网卡发送/接收的频率可能是不一样的,所以就通过这些 1010 来让彼此找到节奏,这个过程叫做时钟复原(recover the clock)
  • SFD: 起始信号(Start Frame Delimiter),估计是 0xAB
  • DST: 目的地(Destination),对方的 MAC 地址(物理设备自带的序号)
  • SRC: 起始地(Source),本机的 MAC 地址(只能在同一个以太网中识别)
  • Type: 用来描述数据部分的类型,如果是 IPv4 则为 0x0800,如果是 ARP 则为 0x0806
  • FCS: 校验序列(Frame Check Sequence),检测传输过来的数据是否出错,采用 CRC 算法

数据部分一般包含更高层协议的数据,比如 IP 包,但是其实具体里面是帧是并不在意的。另外数据尾部可能有一串用来填充的 0,因为数据有一个最小长度限制。

集线器与交换机

我们现在把想要发送的数据打包成帧,然后要怎么发送呢?老一点的方式是通过集线器,而目前基本上都是通过交换机。

集线器的每个端口都会连接一台计算机,一旦有一台电脑把帧发送到集线器,就会自动转发到其他所有的端口,由每台计算机进行检测,如果不是 DST 的话,就忽略这一帧。这种机制实际上有两个问题:

  1. 两台计算机的通信在同一个以太网上是公开的,甚至都不需要去截获,帧自己就会推送过来。虽然信息本身可以加密,但是能够知道发送信息的时间和规律,也并不是特别安全的做法
  2. 因为每次都需要广播消息,所以实际上集线器不能同时发送信息,一旦冲突,就等待一段时间再进行发送

交换机解决了这两个问题,一是记录各个设备的 MAC 地址,按需发送的同时也允许多路同时通信。正因为如此,交换机取代集线器也就非常理所当然了。

网络互联层

如果我们想让一台连接 Wifi 的计算和一台连接以太网的计算机通信,只使用网络接口层的『帧』是万万做不到的,因为有线和无线并没有办法进行信号的传输,所有我们需要一个桥梁,也就是路由器(router)。路由器可以在 Wifi 和 以太网之间发送/接收数据,这样一来就把中间欠缺的环节补上了。但是还有一个问题,我们来看看整个通信过程:

Computer1(Wifi) <-> Router(Wifi) <-> Router(Ethernet) <-> Computer2(Ethernet)

这里需要四个地址!但是一个帧里面只有 SRC(起点)和 DST(终点)的地址,所以我们就需要在前面的数据(payload)中添加信息,来完成信息的传输,于是便有了 IP 协议。

IP 协议

网络互联层是互联网最重要的根基,通过几乎一统的 IP 协议构成了我们今天的互联网。更高层的协议,无论是 TCP 还是 UDP,必须通过网络层的 IP 数据包(datagram)来传递信息。操作系统也会提供该层的 socket,从而允许用户直接操作 IP 包。

IP 协议现在有 IPv4 和 IPv6 两个版本,比如下面就是 IPv4 的格式:

其中 source 和 destination 的长度都是 4 字节,我们通常会把每个字节转化成一个 0-255 的十进制整数,记为类似 192.168.0.1 这样的形式。

IP地址是全球地址,它可以识别局域网和主机。这是通过将IP地址分类实现的。

IP class From To Subnet Mask
A 1.0.0.0 126.255.255.255 255.0.0.0
B 128.0.0.0 191.255.255.255 255.255.0.0
C 192.0.0.0 223.255.255.255 255.255.255.0

每个 IP 地址的 32 位分为前后两部分,第一部分用来区分局域网,第二个部分用来区分该局域网的主机。子网掩码(Subnet Mask)告诉我们这两部分的分界线,比如 255.0.0.0 (也就是8个1和24个0)表示前 8 位用于区分局域网,后 24 位用于区分主机。由于 A、B、C 分类是已经规定好的,所以当一个IP地址属于 B 类范围时,我们就知道它的前 16 位和后 16 位分别表示局域网和主机。

而在具体传输的时候,需要依赖路由器中的路由表,在不同机器间传递的时候,改变的只有帧中的 SRC 和 DST,而 IP 包的内容在帧的 Payload 中是不会变化的。但是现在问题来了,我们怎么知道 IP 和 MAC 的对应关系呢?这里就是 ARP 协议发挥作用的时候了,它会把IP 地址与 MAC 地址的对应传播到局域网的每个主机和路由。而路由表除了可以手动进行编写外,也可以使用 RIP(Routing Information Protocol) 来根据距离进行生成。

IP 协议是 “Best Effort” 式的,也就是说是不可靠的(如果失败了就失败了),但于此同时也是的 IP 协议效率很高,至于更加可靠的传输方式,就要靠传输层实现了。

除了 IP 协议之外,网络互联层一个很重要的协议是 ICMP(Internet Control Message Protocol) 协议,它介于网络层和传输层,主要功能是传输网络诊断信息。我们常用的 ping 命令就是基于 ICMP 协议的。

传输层

现在我们已经能在两台计算机之间进行通信了,但是问题来了,每个计算机有不同的进程,如果我想指定找远方计算机的某个进程要怎么办呢,IP 协议又不够用了。所以传输层协议(TCP, UDP)使用端口号来标注进程,在传输数据的时候,我们写上目的进程的端口。当数据到达另一台计算机时,会根据传输层协议,识别端口号,将信送给不同的进程。

传输层最重要的协议是 TCP 协议和 UDP 协议。TCP 协议复杂但传输可靠,UDP 协议简单但传输不可靠,接下来我们来简单了解一下这俩协议。

UDP

UDP 协议其实并没有在 IP 协议的基础上做太多额外的工作,主要是为 IP 协议增加了端口的支持,头部如下:

从上图就可以看到,UDP 的头部很短,只是额外包含了端口信息,可以看作是 IP 协议暴露在传输层上的接口。

TCP

TCP(Transportation Control Protocol)协议与 IP 协议是一同产生的,或者说,他俩一开始就是同一个协议,后来才被拆开的。TCP 因为实现了『流』式通信,在特定场景中非常有用。具体『流』式通信的实现这里就不展开了,我们来看看 TCP 协议的头部大概就知道它要比 UDP 复杂多少了:

在 TCP 传输数据之前,需要先进行连接,这个过程就是我们常说的 TCP 三次握手(three-way handshaking)。而结束联结的时候也需要进行双方互相确认的工作,就是我们常说的 TCP 四次挥手。

TCP 是一个非常复杂的协议,感兴趣的同学可以在参考链接中找到非常详细的说明,这里我就不再赘述了。

应用层

传输层协议其实在大部分时候已经能够满足我们的需求,但是随着网络应用的增加,不同类型的应用也慢慢有了自己的一套规则,就是我们所说的应用层协议了,比如 HTTP, FTP, IMAP, DNS 等等。这里我们简单介绍一下 HTTP 协议。

HTTP 使用的是『请求(request)』-『回复(response)』机制,客户端向服务器发送请求,而服务器给客户端发送回复。具体回复的状态会在返回的信息中以状态码的形式进行表示。早期发送请求的时候,都需要重新进行 TCP 连接,网络开销很大,同时每次的通信也是无状态的(stateless)。现在 HTTP 协议允许 TCP 链接复用,但是这种无状态的特性依然保留了下来。

试一试

  1. 访问 wdxtub.com,看看在这个过程中数据是如何传输的
  2. 试着 ping 一些地址,看看返回的信息是什么

总结

本文中我们简单了解了计算机网络的基本概念和常用协议,如果有需要,会在后面的系列中进行深入讲解。

(写此文时精神状态不佳,振作后再进行修订)

参考链接

您的支持是对我创作最大的鼓励!

热评文章