网络编程:协议

互联网( Internet ),又称国际网络,是网络与网络之间串联形成的庞大网络,这些网络以一组通用的协议相连,形成了逻辑上的单一巨大网络;简单来说就是,互联网的核心是一系列协议,统称为“互联网协议”,这些协议规定了电脑如何连接和组网。

互联网分层模型

从逻辑实现的角度来看,互联网被分为了好几层,每一层都有自己的功能,就像建筑物一样,每一层都需要依赖下层支持。


按照不同的模型划分( OSI 七层模型、TCP/IP 四层或五层模型 ),互联网会有不同的分层;但不管怎么划分,越往上的层越靠近用户,越往下的层越靠近硬件,理解互联网,需要自下而上理解每一层的实现的功能。


# 物理层

所谓物理层,简单来说就是,把计算机连接起来的物理手段;

我们使用计算机与外界进行通信,首先需要将其连接网络,可以使用双绞线、光纤、无线电波等,这就是“物理层”。

它规定了网络的一些电气特性,作用是负责传递 0 和 1 的电信号。


# 数据链路层

数据链路层,位于“物理层”的上方,用于确定物理层传输的 0 和 1 的分组方式和代表的含义。

单纯的 0 和 1,并没有任何意义,所以,作为使用者,我们需要为其赋予一些特定的含义,规定解读电信号的方式,

如,多少个电信号算一组 ?每个信号位有何意义 ?

早期,每家公司都有自己的电信号分组方式,后来,一种叫做以太网( Ethernet )的协议,逐渐占据了主导地位:

— 以太网规定,一组电信号构成一个数据包( 帧,Frame ),每一帧分为两个部分:标头( Head )和数据( Data )

  • 标头:包含数据包的一些说明项,如发送者、接收者、数据类型等;长度规定为 18 字节
  • 数据:是数据包的具体内容;长度,最短为 46 字节,最长为 1500 字节

So,整个帧,最短为 64 字节,最长为 1518 字节;如果数据过长,就需要分割成多个帧进行发送。

— 发送者和接收者如何进行标识呢 ?

以太网规定,连入网络的所有设备,都必须具有“网卡”接口,数据包必须是从一个网卡,传递到另一个网卡;网卡的地址,就是数据包的发送和接收地址,又叫做 Mac 地址

每块网卡出厂的时候,都有一个全世界独一无二的 Mac 地址,长度是 48 个二进制位,通常用 12 个十六进制数表示;
前 6 个十六进制数,是厂商编号,后 6 个,则是该厂商的网卡流水号

SO,通过 Mac 地址,就可以定位网卡和数据包的路径了

— 我们通过 ARP 协议来获取接收方的 Mac 地址,有了 Mac 地址后,如何把数据准确的发送给接收方呢 ?

在这里,以太网采用了一种很“原始”的方式,它并不是把数据准确的发送给接收方,而是想本网络内所有计算机都发送,让每台计算机读取这个数据包的“标头”,找到接收方的 Mac 地址,然后与自身的 Mac 地址进行比较,如果二者相同,就接收这个数据包,做进一步处理,否则,就丢弃这个数据包。

这种发送方式,就叫做广播( Broadcasting )


# 网络层

按照以太网协议的规则,我们可以依靠 Mac 地址来向外发送数据。

理论上,依靠 Mac 地址,自己电脑的网卡可以找到世界上另一个角落的某台电脑的网卡了;但是,这种做法有一个重大的缺陷:以太网采用广播的形式发送数据包,所有成员人手一“包”,这样做不仅效率低,而且发送的数据只能局限在发送者所在的子网络。也就是说,如果两台计算机不在同一个子网络,广播是传不过去的,而这种设计是合理且必要的,因为如果互联网上每一台计算机都会收到互联网上收发的所有数据包 ...,这并不现实

So,必须找到一种方法,区分哪些 Mac 地址属于同一个子网络,哪些不是;如果是同一个子网络,就采用广播方式发送,否则,就采用“路由”方式发送,这造就了“网络层”的诞生。

— 网络层,引进了一套新的地址( 网络地址,简称网址 ),使我们能够区分不同的计算机是否属于同一个子网络

网络层出现后,每台计算机就有了以下 2 种地址,二者之间并没有任何联系

  • 网络地址:~ 是网络管理员分配的,用于确定计算机所在的子网络,
  • Mac 地址:~ 是绑定在网卡上的,用于将数据包发送到子网络中的目标网卡

So,从逻辑上可以推断,先处理网络地址,再处理 Mac 地址

— 规定网络地址的协议,叫做 IP 协议,所以,它所规定的网络地址,又被称为 IP 地址

目前,广泛采用的是 IP 协议第 4 版,简称 IPV4
该版本规定,网络地址由 32 个二进制位组成,我们通常习惯使用分为四段的十进制数表示 IP 地址,从 0.0.0.0 到 255.255.255

使用 IP 协议发送的数据包,叫做 IP 数据包( 整个数据包的最大长度为:65535 字节 ),它,也分为以下两个部分:
-- 标头:主要包括版本、长度、IP 地址等信息,长度为 20 到 60 个字节
-- 数据:IP 数据包的具体内容

# 传输层

有了 Mac 地址和 IP 地址,我们就可以在互联网上任意两台主机之间建立连接。

— 但,同一台主机上,会有许多程序都需要用网络收发数据,Then,如何区分某个数据包到底归属哪个程序呢 ?

So,我们还需要一个参数( 端口,port,本质上是每一个使用网络的程序的编号 ),表示这个数据包到底供哪个程序( 进程 )使用;这样,每个数据包都发送到主机上的特定端口,不同程序就能取到自己所需要的数据了。

端口,是 0 到 65535 之间的一个整数,正好 16 个二进制位。
其中,0 到 1023 的端口,被系统占用,所以,用户只能选择大于 1023 的端口使用

有了 IP 地址和端口,就可以唯一确定互联网上的一个程序,进而实现网络间的程序通信。

— 我们需要在数据包中加入端口信息,这就需要新的协议:UDP 协议  /  TCP 协议

  • UDP 协议:最简单的实现方式,它的格式几乎就是:在数据前面,加上端口号。其优点是,比较简单,容易实现,但,缺点是,可靠性较差,一旦数据发出,无法知道对方是否收到
UDP 数据包,也由标头和数据两部分组成
-- 标头:主要定义了发出端口和接收端口
-- 数据:具体的内容

UDP 数据包,非常的简单,标头部分一共有 8 个字节,总长度不超过 65535 个字节,正好可以放进一个 IP 数据包
  • TCP 协议:为了解决 UDP 协议的缺点,提高网络可靠性,TCP 协议诞生了。它能够确保数据不会丢失,缺点是,过程复杂、实现困难、消耗较多的资源;TCP 数据包,没有长度限制,理论上可以无限长,但为了保证网络的效率,通常 TCP 数据包的长度不会超过 IP 数据包的长度,以确保单个 TCP 数据包不必再分割

# 应用层

应用层在收到传输层的数据后,需要做的就是对数据进行解包。

互联网是开放架构,数据来源 ...,必须实现规定好通信的数据格式,否则,接收方根部无法获取发送的真正数据内容

So,应用层( 如,TCP 协议上常见的 HTTP、FTP 等协议 )的作用就是:规定应用程序使用的数据格式

如下所示:发送方的 HTTP 数据,在互联网的传输过程中,会依次添加各层协议的标头信息,接收方在收到数据包后,再依次根据协议进行解包,得到数据