分层是网络里面最重要最基础的概念了,也是这里面第一个充满了设计理念并且在实际运用中被程序员们修正为更符合实际运用的设计。这是我认为最工程的事情之一,先有设计,然后再实践,最终在不断的实践中修正为更好的设计并且指导后人。废话不多说了,扯扯正题。

    你只要在搜索引擎上搜索网络分层,最多的两个图一定是下面这两个:

     分层  - 图1

    左边的一般称之为0SI七层参考模型,注意参考两个字,右边的一般叫TCP/IP五层模型(貌似也有很多把物理层和数据链路层合并了叫4层模型,不过我还是习惯5层模型)。为什么要分层,我想先举个现实的例子,比如说你要从A地寄快递给B地,那么现实中我们只要做一件事,将对方地址填写正确,然后交给快递公司。你不用考虑快递用什么方式运到B地,经过多少城市多少收费站才能到B地。同样在网络初代通信的时候,大神们发现很多不同的计算机之间通信要处理好多问题,比如编码,控制怎样开始结束等等,甚至还要关心我这里和你那里到底用什么介质链接起来。这样很多问题往往会混杂一起会降低本身对核心业务逻辑的思考,而且很多的东西交织在一起有时候让简单的问题复杂化。于是在商业,工业和科研一起的努力下,国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)就推出了这么个指导模型,将复杂的网络问题简化为一层一层的方式,每一层只管自己的事情并将自己的输出交给自己下一层,或者从上一层接收到输入进行处理,每一层都各司其职而又紧密配合,多么好的组织模式。但是在实际中,工程师们在经过实践之后发现分为7层有点复杂了,考虑到在各个场景中操作系统已经把问题简化到一般就只有内核态和用户态,所以从中简化出更加简洁的5层模型,有点精简机构,提高效率的意思。所以,在5层结构中,除了应用层之外,其他的基本都在内核中实现,换句话说,绝大数领域,绝大多数情况下你可能不用考虑我怎么保证我的数据完整的传到了对方,如果中间网络断了怎样重传,最多就是通过已经提供好的接口设置一下参数。

    为了更直观的详细介绍分层,我想先用一个我能想到的个人觉得最接近的现实场景来阐述,就是物流。还是要运东西从A到B,应用层可以理解为你要运啥到B地,是普通快递,还是蔬菜生禽,还是工业材料等等,只要你和B地的人约定好要寄什么这就是这一层的事情。然后你要像物流公司或者快递公司提供对方的详细地址并交给物流公司的办事点,这时候就完成了应用层的输出(要运送的物品)交给传输层,传输层也完成了自己的输出——带有详细地址的物流单。这时候物流公司的物流管理部门拿到物流单,也就是上一层的输出,物流公司所关心的只是运送到哪个城市,工作人员会忽略门牌号,该部门工作人员只会设计运送到那个城市的路线,于是网络层这件事情也处理好了。接下来就开始运送货物,运输时归物流公司的运输部门进行具体负责的,他会统筹货物并且打包成他认为空间利用率最高的方式然后交给真正的运输师傅,在这一层是不用管我到底是用飞机,汽车还是火车运输,只有最底层的师傅根据两个城市的实际情况选择最合适的运输方式。这样,每一层只干自己的事情而不用操心其他的层的逻辑,需要做的只是做好自己事情并且交给下一层就行了。

    就和物流是将真实的货物从一个地方运送到另外一个地方一样,网络是将虚拟的bit从一端运送到另一端。但是由于其更加的抽象并且更加的复杂,分层就自然是很必要的一件事情了。过头来再来看看网络中的分层,由于OSI的七层模型只是参考模型,在这里我还是主要介绍更贴近于编程实际的5层模型。

    物理层,是5层模型的最底端一层,主要负责物理上的网络的链接,断开,并且维护这个物理链接。再具体点,就是用啥材料组网,怎样编码,电流或者光调制等等。这些听起来就离程序员很远,所以说也确实实际中能接触到这一层的概率微乎其微。但是即使在一点知识也不知道的情况下,对于这一层应该记住的关键词是介质和信号。 类比路由概念,这一层就是到底是天空,高速公路还是土路等等。

    再往上就是数据链路层,这一层主要是在物理层的基础上为网络层提供服务,这种服务就是保证来源网络层的数据能够完整无误的传输到另一端的网络层。具体来说就是在这一层需要考虑如何把数据组织成数据块,如何对每一个传输数据块提供错误校验以保证完整无误的传输,甚至有的网络链路层还提供流量控制的功能。对于这一层最应该记住的关键词是MAC和ARP协议。世界上的所有计算机想要加入网络这个大家庭互相通信,首先第一步都需要拥有一块网卡,而这块网卡拥有一个MAC地址,而这个就像我们的身份证号码一样,是唯一的。至于ARP,正好放在下一层来介绍。

    数据链路层之上就是网络层,说起来这一层最重要的功能就是负责主机到主机的传输。所谓的IP地址就是定义在这一层,它定义了能够标识所有结点的逻辑地址,还定义了路由的各种方法,最大传输的包的长度。这样说来有点抽象,其实类比物流的概念的话,这一层主要就是设计两个城市之间的路线,路由嘛就像是城市之间的收费站,你想到另外一个城市,基本上就一定要经过收费站,不然你就只能在自己的城市里转转。所以说对于这一层,最应该记住的关键词是IP地址,路由器。至于刚才说的ARP,负责了从IP地址到MAC地址的转换,而IP地址就像我们的名字是可以重复的,所以说真正的网络通信是不能依靠IP地址的。

    再往上就是传输层了,这一层主要负责在端口到端口的传输,你可以认为这是在主机到主机传输之上又实现了一层更加精细而又可以服用的逻辑端到端,这一层负责的东西很多,包括流量控制,差错处理,甚至重传等等。所以大名鼎鼎的TCP,UDP等等都工作在这一层。和前面的一样最起码对于这一层也要记住的是,端口,TCP, UDP。

    在这些层最上面的就是应用层了,这可能是和程序员接触的最多也是最多姿多彩的一层,你可以根据自己的需要实现各种各样的应用。比如说HTTP,FTP等等。

    综上所述吧,我做了一个表格,我觉得能记住这些对应的关键词差不多就达到了一个程序员了解的程度了。

    数据块名称关键词
    应用层DataHTTP,FTP,SMTP等等
    传输层Segment(TCP)/Datagram(UDP)TCP,UDP,端口
    网络层PacketIP,路由器,DHCP
    数据链路层FrameMAC地址,ARP协议
    物理层Bit信号与介质

    其实我第一次看到这些知识的时候,有一个疑问就是,这些玩意儿有什么用?在编程中真的能用到这些东西吗?很明显没在编程中直接运用到这些知识的地方很少,但是这些却是网络编程的一个框架,不了解这些,到后面很多的时候当名词越来越多的时候自然会感到越来越繁乱,而且发现理不清头绪。如果非要说实际中一个重要做用的话,至少在面试中当面试官问到这种基本的问题的时候,你能够对答如流,不能说三次握手了然如胸但是分层却是一问三不知,给人知其然不知其所以然的把柄。

    而这些对于各层的介绍都过于抽象了,而作为一个工程人员还对摸得到看到着的最有感觉,所以下一篇我用一个实际的例子加上wireshark具体的展示一次各个层级的样子。