熟悉又陌生的TCP/IP

TCP/IP协议的诞生

说到 TCP/IP协议 我相信各位光头们并不陌生,那他怎么变得如此流行的,我想有个很重要的原因,刚好生在他应该诞生的时机。

期初,军用方面的应用,需要进行信息的交换,所以有一套这样的网络:

网络

这样就有一个问题,如果中心节点被敌人偷袭了,那么整套军用系统就全部瘫痪。那为了防止这种事情的发生,我们可以多加几个中心节点:

这样的话如果中心的节点被袭击了(变成红色表示故障),那么其他计算机还可以通过比较远的输送距离将数据传达到彼此。

这种网络,叫做 Advanced Research Projects Agency Network 阿帕网,其实这个翻译完全覆盖了他的意思,英文翻译过来应该是 可重新查找项目的网络

那么这个网络,由于连接的不稳定性,就需要有一个协议来保证传输的完整,那么这个 阿帕网 中的一些研究机构,就研究出了 TCP/IP协议。这时候,他还没那么流行。这时候很多大学和研究机构开始使用一款叫做 BSD UNIX 的操作系统,由于这套系统中实现了 TCP/IP协议,并且随着互联网的发展,这个系统受众越来越多,这就导致了很多网络设备供应商不得不去适配 TCP/IP协议,所以到如今才使 TCP/IP协议 的应用变得如此广泛。

TCP/IP协议的内容

TCP/IP协议 并不单单只是包含 TCPIP 两个部分,其实他是一个族:

  • 应用协议:HTTP、SMTP、FTP、TELNET……
  • 传输协议:TCP、UDP
  • 路由控制协议:RIP、OSPF、BGP……
  • 网络协议:IP、ICMP、ARP……

每一部分内容单独拎出来都是一大块的内容。

其二,他与 OSI七层模型协议 不同,但是有其对应的地方,引用一张图(via 《图解TCP/IP》)

与七层模型的匹配

可以看出,OSI七层模型协议 被简化了很多东西:

  1. 数据链路层(包含网卡+电缆):这一层肯定必不可少的,不然没有通电就无法传输数据,其中的网卡 MAC地址 会被用来确认当前接收的数据是否需要交给本机进行处理,如果跟当前本机的 MAC地址 不相符合,那么传送过来的数据包将会被抛弃掉;
  2. 互联网层:IP,在上面说 OSI七层模型协议 的时候我们有说过,当 数据链路层 接收到数据的时候,此时还不能确定数据包就是当前机器需要接收的数据包,还需要判断 IP地址 是否指向本机,我们知道一台机器我们是可以在操作系统上面指定分配多个 IP地址 的,如果判断是的话紧接着将数据上送给传输层;
  3. 传输层:传输层我们通常需要指定数据需要到达的端口,现代计算机一般都是同时运行好几个程序,更别说端口占用的那就更加多了,端口刚好就是可以指定数据要交给哪个应用程序进行处理的方式。除了端口的作用,还有保证数据是否需要判断接收成功失败的作用,比如 TCP协议 或者 UDP协议
  4. 应用层:在 TCP/IP协议模型 中,将之前所说的 应用层表示层会话层 都集中在这一层中进行处理,如果开发过 Netty 相关项目的同学就知道,我们通常需要处理 粘包 丢包 等问题,如果有时候需要加快传输速度但又不允许丢失数据的时候,通常需要 UDP协议 + 我们自己的校验 去验证数据是否传输完整。常见的应用层协议有:HTTPFTPSSHSMTP 等;

那么数据是怎么流动的呢,跟 OSI七层模型协议 模式是一样的,不过不需要包 七层 的头部数据。

  1. 在这里我们通常只需要应用将数据进行包装,然后以一定的编码进行处理(通常是 UTF-8)交给 传输层

  2. 然后 传输层 将会根据不同的协议(一般是 TCP 或者 UDP)将我们的应用数据再包上一层协议本身的 Header;然后交给 互联网层互联网层 则再包上 IP头 将数据交给 数据链路层,注意了,在这一层,如果尚未知道下一层所需要的 MAC地址 的话,会利用 ARP(Address Resolution Protocol) 进行对端的 MAC地址 查找,然后再交给下一层;

  3. 数据链路层 则是包上相关的 MAC地址 信息,然后交给驱动进行网卡适配,然后发送数据。

最后数据将会被包成这样发出去(via 《图解TCP/IP》):

传输数据结构

而接受数据方面:

  1. 数据链路层 接收到数据以后,会判断 头部Header 是否是给自己的,如果不是则会抛弃数据,有时候收到的不是 IP数据包 而其他协议,则会相对应的交给对应的模块进行处理(例如:ARP 协议);
  2. 互联网层 也跟 数据链路层 处理方式相似,但是如果接收端的地址与本机地址不符合的话,会借助路由器的 路由控制表,调查下一个应该到达的主机或者其他设备以后将数据进行转发;
  3. 传输层 则会对接收到的数据进行校验,并且根据接收到的数据包的序列化重新排序,交给对应端口的 应用层 进行处理,同时通知 发送端 告知数据已经接收完成,如果这个接收通知不能到达 发送端发送端 会不停的重发数据直到被告知数据接收完整;
  4. 应用层 这方面就太熟悉了,可以正确接收正确处理,也可能引起一些其他协议方面或者业务方面的错误,从而处理出现异常,比如我们常常遇到的 404 Not Found

OK,那现在开始先从低层架构开始了解。


数据链路层

数据链路层对于我们开发来说其实不是特别重点,所以只需要简单的了解一些基础内容即可。

主要作用

数据链路层其实就是连接世界上所有计算机的基础,我们了解到,其实计算机的机器码是 10,那么人们发现这个跟电路中的 可以对应起来,所以我们就可以使用电平的 来表示机器码信息,从而利用电路等物理介质将计算机信息传递给另外一台计算机。(如果是光纤则可以使用 这两种信号来表示 10

然而,物理层也不是单纯的发送 10 信号,而是把这些数据通过一定的规则,集合起来,作为 去发送数据( 的内容会在后面细说)。

连接拓扑

一共有四种连接的拓扑方式:

1. 总线型

总线型

就是中间一条总的网线,然后在不同的接口处连接计算机,这种方式应该算是比较古老的,如果总线某一段发生故障的话,那么被影响的计算机也不确定。

2. 环形

环形

环形中的计算机并不相互连接,那么如果我们发送数据到不连接的计算机的时候,就需要其他计算机来参与传送。比如说,将数据从 A计算机 发送到 C计算机,那么数据得先发送给 B计算机,然后 B计算机 再判断数据是否是给我这个网卡的(利用 MAC地址),如果不是,则顺着网线传输给下一台计算机 C。这时候 计算机C 才算是接收到数据。但是如果这个过程中,计算机B 发生了故障或者硬件支撑不住的话,那么 计算机C 接收数据将会受到影响。

3. 星型

星型

这种方式应该是目前最流行的方式了吧。无论是办公室或者网吧等等,都可以使用这种连接方式。每台计算机只要专注自己要做的事情即可,不用管其他的问题。但是有个最主要的点就是需要保证中央集线器的正常运行,如果中央集线器挂了,那么所有计算机都无法进行数据的传输。

4. 混合型

混合型

顾名思义,混合不同的连接方式,这种可以根据我们的日常工作需求,用于降低计算机连接成本,当然按照目前硬件的价格低廉的特性,一般都是使用 星型 的架构来混合。

以上几种方式的计算机连接是 网线 中布局的方式,先简单的记忆即可,然后我们来看看微观的数据是怎么传送运输的。

MAC地址

用于与网络连接的设备,诸如 网卡无线LAN蓝牙模块 均拥有 MAC地址MAC地址 是由生产该设备的厂家规定的,并且烧录到硬件设备的 ROM(Read Only Memory) 中。任何网卡的 MAC地址 均是世界性的唯一的(类似于我们的身份证)

而世界性唯一这个性质也不是说就是绝对的,如果两个相同 MAC地址 位于不同的数据链路中,那么他们一般也不会相互影响到。比如中国的网卡 和 美国的网卡,共用了一个 MAC地址 通常来说除非这两台计算机组成了一个什么虚拟云才会相互影响,不然一般都可以正常的工作。

MAC地址 一共 48位

不同的位数表达不同的内容:

  1. 1 位:0表示单播地址,1表示多播地址;
  2. 2 位:0表示全局地址,1表示本地地址;
  3. 3 - 24 位:由 IEEE(美国电气和电子工程师协会) 管理并且保证各个厂家之间不发生重复;
  4. 25 - 48 位:由厂家管理保证产品之间不重复。

然而在这里我感觉得先弄清楚 比特位字节 之间的区别:

比特位:由 0 和 1 两种信息表示,比如 101010 则拥有 6 个位

字节:一般情况下,1个字节有 8 个比特位,比如 10101010 表示 1 个字节

所以这里的 48 位表示 6 个字节数。

数据比特流 在网络中的流动顺序,是按照 每一个字节 倒序传输的,一个图解释:

1
2
这是我们要传输的数据:0 0 0 0 0 0 0 1 | 1 0 0 0 0 0 0 0 
这是比特流中流动数据:1 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1

那么我们的数据已经来到了目前计算机的网卡了,接下来肯定就要进入介质了,所以我们来看看介质的传输过程。

介质传播数据

介质传播的分类,我们可以按照上面 拓扑连接 来进行简单的分类:

共享介质型网络

共享介质一般出现在 总线型环形 的拓扑连接方式里面,总线型 就是多台计算机共享一个网络传输介质(多为网线)的方式,那么这种工作方式就出现了一种问题:需要争抢共享的资源。所以这种方式是一种 半双工 的工作方式(就是说只能单独处理发或者收)

如图,在某个时刻,计算机B 需要传输数据给 计算机C,那么他会观察总线上是否有数据正在传输,而此时并没有数据进行传输,所以他就占用了总线这个资源,向其他计算机分别发送了数据包。

此时其他数据包接收到数据包的时候,就需要判断数据包包含的 MAC地址 是否指向了当前计算机的 MAC地址,如果不是,则将数据进行丢弃。而 计算机C 接收到数据包后,判断是 MAC地址 指向了自己,所以就开始处理数据。

而如果 计算机B 在发送数据的时候,计算机C 也需要发送数据的话,就需要主动放弃数据,释放载波信道,等到 总线 中的电压稳定以后,再重新发送数据。

而另外一种 共享介质 的拓扑结构就是环形结构,为了有效提高数据的传输效率,提出了令牌的说法,即在环形中所有的计算机如果需要发送数据,则需要先获取令牌才可以向其他计算机发送数据:

以上两种方式看起来都是蛮老的技术了,简单分析就可以知道,网络的利用率很低。所以衍生出了下面这种方式。

非共享介质型网络

非共享介质 的网络则采用一种设备:交换机。交换机可以单独连接不同的计算机,然后计算机都是可以通过 全双工 的方式进行数据传输的。交换机本身拥有一些功能,可以将数据缓存,然后自动的判断闲时,将数据发送给对应的计算机。

计算机A 发送的数据中会标明 原地址为A目标地址为C,交换机拿到这条数据以后,只要根据 目标地址 的标签来发送数据就可以了。这样就可以很明显的提高网络的传输效率。

现代的交换机都会带有 自学习 的功能,也就是自学哪个端口连接了哪台计算机,MAC地址 是多少,这样就可以很高效的对数据进行转发。相当于已经自带路由表。

VLAN

这一层属于软件层面上的管理了。意思是即使在一个区域内,计算机都连接到同一个交换机上,我们也可以通过软件管理,将这些连接的计算机根据我们自己的日常需求,划分为不同的子网段。这样做的好处就是,即使我们的日常计算机发生了功能上的变更,管理员不用去更改网络拓扑的结构,只需要在软件层面上对这部分计算机进行网络功能的划分即可。

即使是两个 交换机,也可以组成同一个网段:

即使两台 交换机 连接的不同计算机,也可以通过网络管理组成在同一个网段中。

以太网

我们前面的内容基本说的是一个局域网的连接,那如果需要访问远程的资源,我们就需要一个网络,称为 以太网(Ethernet) 了。而以太网可以说就是使用多个 交换机 连接在一起,成为一个很大的 局域网。每一个以太网连接着多台计算机。每台计算机又运行着不同的 WEB程序。这样我们需要不同业务需求的时候比如 买票 发邮件 只要通过网络到达能够实现功能的计算机即可。

而不同的以太网版本,又有不同的物理实现方式(via《图解TCP/IP》):

以太网不同版本的物理介质

而如果需要延长距离的话,则需要加上之前说过的设备:中继器 或者其他可以放大信号的设备。

以太网帧格式

以太网帧以一个叫做 前导码 的数据开始,这个 前导码 占用 8字节(64位) 空间,以 1010... 的形式开始,而使用 11 这两位结束 ,比如:

1
10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101011 后面紧接着帧本体(14字节)

帧本体占用 14字节,前 6字节 记录 目标MAC地址(上面说了MAC地址是48位数),紧接着 6字节 记录 源MAC地址,然后 2字节 记录上层协议类型,帧尾则以一个 4字节 的叫做 FCS(Frame Check Sequence) 的数据进行结尾(类似于我们的 MD5 验证数据的完整性),用于目标机器验证数据是否完整或者是否遭到破坏。

所以一个完整的帧:

以太网帧

那我们可以计算得出,一个 以太网帧 能够传送 70-1524 字节的数据(每一位做什么事情都被安排的明明白白),大概是 1.5m。但是需要除去一些必要的头部信息,所以其实留给应用程序的空间并不是很多。

上面只能算是一个 通用的帧格式,而如果根据协议的不同(比如 VLAN 还会重新规划),则会大概的重新规划 协议数据 这两部分的空间利用。目的当然是为了提高网络的传输速率。

哦对了,协议我们常见的编码对应是(via《图解TCP/IP》):

协议版本

这里是 16进制 注意需要转换成 2进制 的,比如 IP 对应的 0800,转换成 2进制 则是 00001000 00000000

无线通信

这部分其实还是蛮好理解的,我们只需要提供一种设备用于接收 电磁波 或者无线信号,然后转成以太网的格式即可介入以太网。

常见的电磁波信号(via《图解TCP/IP》):

常见的电波信号

分层结构(via《图解TCP/IP》):

无线通信分层结构

这里有个冷知识:微波炉使用的是 2.4GHz频段 的微波,如果在一台正在工作的微波炉旁边,我们的路由器设置 2.4GHz频段 的话,则传输数据的信号会受到干扰。

PPP(Point-to-Point Protocol)

PPP协议 可以解决一系列的问题:验证你有没有交费、给你分配一个网络IP等问题,所以一直是 ISP 用来提供给用户上网的一种形式。

我们打开 宽带连接,点击连接的时候,通常是把用户名和密码进行压缩发送给 ISP 进行验证,然后 ISP 会分配一个 IP地址 给到客户端,然后我们客户端就可以网上冲浪了。

连接过程(via《图解TCP/IP》):

PPP连接过程

说完了 链路层 的事情以后,我们可以上升一层了,来说说 IP 的事情。

下一节再说。