本节主要介绍操作系统是如何处理网络请求的。当一个网络包到达时,操作系统如何把这个网络包传递给应用程序;应用程序GET,POST一个请求的时候,操作系统如何将这个请求打包发送出去。
首先网络是典型的分层模型,从操作系统的角度来看,可以简化为数据链路层,IP层,传输层,应用层4层。这里的层级不要与OSI的7层模型混淆。这里是另外一个简化模型。对于各层简要介绍一下:
数据链路层:这层的数据叫做帧,每个帧都有固定的头部标志和尾部标志,操作系统通过判断首尾标志来从比特流中区分出一个一个的帧。帧的头部有源MAC地址和目的MAC地址,帧的路由方式依据这两个MAC地址来进行。网卡看到一个帧到来时,如果该帧的目的MAC地址与自己相符,则处理这个帧,否则丢弃。
网络层:网络层是数据链路层的载荷,数据链路层不关心网络层的内容是什么,帧解包以后剩下的内容就是网络层的内容,目前网络层使用最多的协议是IP协议,ICMP协议等,由于IP协议用途很广,我们就IP协议来介绍,IP层有一个比数据链路层更复杂的包头,里面包含了这个包的信息,包括源地址,目的地址,头部长度,总长度等等,操作系统通过阅读头部来了解这个数据包的信息,从而解包和路由。值得注意的是,IP层的一个完整的包可能包括多个分片,一次网络发送不一定能够发送完一个完整的IP包,因此每个IP包的头部会包含自己的分片ID和分片偏移,操作系统根据这个将这些分片再组装成一个完整的IP数据包后再交付上层或者转发。
传输层:传输层是IP层的数据,里面包含了源端口和目的端口的信息。所有的IP数据包到达操作系统后并不能立即交给应用程序,操作系统需要通过端口号来对进程进行区分,然后将包分发给不同的进程。
应用层:这里就进入用户空间了,是具体的程序逻辑,操作系统剥离了传输层的包头后,将最终的内容交给用户的程序。如果你是直接操作socket的,那么socket通过read()读到的数据就是这部分了。如果你是通过http这样的协议来通信,那么还需要对传输层的内容再进行解包,获取最终的信息。
数据包发送的过程则是和上面的解包过程相反。
深入到内核部分,再来看这些过程,这里最重要的一个数据结构就是sk_buff,一个sk_buff对应了一个帧。操作系统见到的最原始的数据就是这个sk_buff了。这个数据结构里包含了mac头部长度,网络层头部长度,传输层头部长度等。操作系统收到一个sk_buff对象后,参考这些头部长度来进行解包,为了性能起见,操作系统解包通过移动指针的方式进行,而非真正的删除包头。sk_buff是操作系统网络部分最核心的数据结构,操作系统协议栈的各层处理实际上就是操作这个结构,可以说是网络子系统的基石。所有的sk_buff被组织成一个队列,实现上是一个双向链表。当一个数据包到来时,经过协议栈的层层处理,最终会被拷贝到用户空间,被read 返回。发送数据包时,过程相反。
————————————————
版权声明:本文为CSDN博主「apt-get-install」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nigh51/article/details/100060925