我们先来探讨一个问题,网络为什么要分层? 网络分层,我们都设计代码时,都会考虑进行分层,比如controller、service、dao层等。在设计复杂的结构时,都会采用分层的方式,这样可以让每一层专注于某一件事情。 在理解计算机网络中的概念时,可以想象网络包就是一段buffer或者一块内存,其是有固定的格式的。同时想象自己就是一个处理网络包的程序,而且这个程序可以跑在电脑、服务器、交换机或路由器上。可以想象自己从一个网口拿到一个网络包,处理完成之后再从另一个网络口发出去。网络分层- 程序是如何工作的呢? 我们可以想象一下这个工作的大致流程: 网络分层,当一个网络包从网口经过时,要先看看需不需要把网络包拿到自己的程序来处理一次。如果网口配置了混杂模式,则凡事经过网口的网络包都拿来处理一次。 在拿进来之后,先通过process_layer2(buffer)这个假函数把二层的网络头从buffer中摘掉,然后根据摘出来MAC地址来做具体的操作。 如果MAC地址和自己本机的MAC地址相等,则说明是发送给自己的,则通过process_layer3(buffer)这个假函数把三层的头摘出来。然后根据IP地址判断是否和自己的相等。 如果IP地址和自己本机的IP地址不相等则说明是要转发出去的,相等则是发送给自己的。在摘掉三层IP地址的网络头之后,就开始判断是调用process_tcp(buffer)还是process_udp(buffer)。 假设是调用process_tcp(buffer),这时就要看四层的网络头来判断这是一个发起、应答或者一个数据包来做不同的处理。如果这是一个发起或应答,接下来就需要发送一个回复包。如果是一个正常的数据包,就要交给上层来进行处理。 一个网络包处理程序在四层处理完网络包之后,就需要交给应用来处理,那交给哪个应用来处理呢?在四层的网络包中是含有端口号的,不同的应用监听不同的端口号。如果浏览器正在监听这个端口号,交给浏览器处理就好。网络分层- 网络分层,当在浏览器展示出页面之后,用户通过点击操作来使用端口号再次发起一个请求,这时会调用send_tcp(buffer)在网络包中添加TCP的头,并添加上源端口号和目标端口号。 接下来调用send_layer3(buffer)在网络包中记录源IP和目标IP地址。接下来通过send_layer2(buffer)在网络包中记录源MAC地址和目标MAC地址,如果不知道目标MAC地址的话,则通过协议来得到目标MAC地址,总之不能空着。 经过上面的处理之后,只要buffer网络包中的数据完整,就可以从网口中发出去了。现在来分析一下TCP在三次握手和四次挥手时IP层和MAC层在做了一些什么? TCP层在每发送一次消息或回复一次消息时,都会经过IP层和MAC层,其所有的机制都会运行一边。 下面来总结一下:网络分层,只要是跑在网络中的包,必定都是完整的。在网路包中,可以有下层没上层,但是绝对不可以有上层没下层。