Linux 网络总结
文章目录
- 1. 网络通信的本质
- 2. OSI与TCP/IP
- 2.1 TCP/IP各层数据名称
- 2.2 TCP/IP的封装和分用
1. 网络通信的本质
在整个计算机世界中,所有的数据信息最终一定是用01表示。所以,最终网络中传输的信息一定是比特流。
比特流本身只是01的排列,是没有任何意义的。而在网络中,两台主机能够正常进行网络通信,就在于它们能够合理地解析对端发送的比特流,而这就说明特定的比特流被人为赋予了特定含义,并进行了特定解析。那么,是什么赋予了比特流含义使得能够进行网络通信呢?答案是网络协议。
协议,本质就是双方约定并且共同遵守的规范,在网络通信中,这种规范基本是特定的数据格式。协议本身是有很多的,单纯有协议依旧无法完成通信,必须通信双方遵守共同的协议才能实现通信,这就好比中国人和中国人交流时,说中国话才能互相沟通,和英国人交流时,需要说英国话才能沟通——能够沟通的前提,本质就是遵守使用相同的协议。
因此,为了实现网络通信,国际标准化组织就制定了一系列网络通信相关协议,其中最知名的协议就是OSI七层模型和TCP/IP五层模型。
无论是OSI协议,还是TCP/IP协议,这些模型都是分层的。这是因为,这些模型最终实际应用于网络通信,而网络通信中实际遇到的问题是层状的,因此这些协议,或者说解决方案就是层状的;另外一个原因则是,这些协议最终本质都是软件,即通过代码实现的,层状设计本质是模块化与解耦合,能够有效降低软件的维护成本。
2. OSI与TCP/IP

网络通信协议中,OSI与TCP/IP二者本质是一样的。
OSI七层模型是最开始提出的,而在后面具体实现中,发现表示层和会话层更多是应用层的内容,应该在应用层实现,难以集成到内核中,因此TCP/IP模型,就将表示层和会话层统一集成到应用层中,变为五层模型,这也是现代网络世界中,应用最为广泛的通信协议。
2.1 TCP/IP各层数据名称
TCP/IP是五层模型,每一层的数据都有特定叫法。
应用层的数据被称为报文,即message;传输层中,TCP被称为TCP数据段,即segment;UDP被称为UDP数据报,即datagram;网络层中,IP协议中的数据被称为IP数据包,即packet;数据链路层中,以太网协议中的数据被称为MAC帧或以太网帧,即frame;物理层中,数据一般被称为比特流。
2.2 TCP/IP的封装和分用
TCP/IP是分层模型,模型为何分层,已在前文做出解释,但是模型分层,也会带来一个问题——层与层之间如何联系,即在整个协议中,发送数据时,如何封装,然后向下传递;接收数据时,如何解包,然后向上分用。
实际上,这两个是逆过程,弄懂其中一个,另一个本质也是相同的逻辑。因此,下面我们重点来讲讲如何分用。
首先,分用是什么?举个简单的例子,传输层有TCP和UDP之分,两者报文在网络层中,最终都封装成IP报文。那么,如果我收到一个IP报文,解包后,是交给TCP,还是UDP呢?如果发送端是TCP,那么自然交给TCP;如果是UDP,那么自然UDP。这个协议中一层解包后,将有效载荷正确交付给上层的过程,就是分用。
我们从最底层开始,讲清楚整个TCP/IP协议栈的分用逻辑。
首先,网络中传输的比特流由网卡接收。在连续的比特流中,网卡如何划清报文界限,确保每次都能接收一个完整的数据链路层报文呢?
如果单纯传输有效数据,而不使用一些特殊的标志位进行人为划分,网卡显然是无法达到上述目的。实际的网络通信中,在一个完整的数据链路层报文前,存在8字节的序列,用来标识一个报文的到来;同时一个完整报文结束后,又有MAC帧间隙来标识报文结束。在这样的双重保障下,网卡一定能够划清不同报文间的界限,保证接收一个完整报文。
网卡接收到完整报文后,对尾部4字节的CRC校验码进行校验后,如果正确,则正常交付给数据链路层一个完整的数据链路层报文。
数据链路层拿到报文后,MAC帧报头内容长度是固定的,因此能够正确解包。而在MAC帧报头中,又有标明上层使用协议的字段,因此能够正常分用。
在MAC帧中,不能直接将去除报头后的内容交付给上层,因为在有效载荷中,可能存在数据链路层的填充内容,因此还要对有效载荷部分做一定解析,确保将真正的有效载荷内容交付上层(完全可实现,arp报文固定大小,IP报文报头大小固定,报头中16位总长度字段标识整个IP数据包的大小)。
网络层以IP协议为例。此时网络层IP拿到IP数据包,此时需要额外考虑分片逻辑,即如果存在IP分片,需要等待所有分片都接收并完成IP分片组装后,再彻底解包和分用。IP数据包的报头大小是固定的,能够正常解包,完成解包后,剩余内容均为有效载荷,同时报头又有标明上层协议格式的字段,因此能够正确分用。
传输层UDP。UDP拿到相应UDP报文后,UDP报头长度固定为8字节,能够解包,剩余部分均为有效载荷。网络通信依赖socket,应用层读取和发送数据,本质是在相应socket的接收和发送缓冲区中做读取或写入。那么UDP如何将有效载荷正确放到相应socket的接收缓冲区中呢?
在传输层中,为了解决上述问题,即能够正确区分socket,内核中维护了一个五元组,即源IP,源端口,目的IP,目的端口以及协议号(UDP或TCP),用这个五元组来唯一标识一个socket,这样数据就能够正确放到相应socket的接收或发送缓冲区中。
因此,上述传输层UDP中,也就能够解决分用问题了。
传输层TCP。TCP拿到相应TCP报文后,报头长度固定为20~60字节,能够解包,剩余部分均为有效载荷,通过上述标识,能够正确放到相应socket接收缓冲区中,完成分用。
应用层。到这一层后,本质已经脱离内核,完全进入用户代码的处理逻辑。通信双方要能正常通信,应用层同样要遵守相同协议。应用层协议五花八门,最常见的一种当属用于WEB服务器访问的http/https协议,关于应用层协议,本篇博客不再赘述。
上述过程,便是在TCP/IP协议标准下,一个网络通信报文的完整分用过程,而报文如何分用解包,逆过程,便是报文如何封装和向下交付,此处不再赘述。
本质上,我们学习网络通信呢,本质就是在学习网络通信协议,学习TCP/IP协议,而学习协议,本质就是在学习了解一个网络通信报文的完整生命周期——从发送端如何发出,到在整个网络,即局域网,广域网中如何传输,到最后被接收端如何接收的完整网络通信流程。
