前段时间买了极客时间的《趣谈网络协议》,这个真的比较有意思,比较容易理解,但是内容需要记忆的东西比较多,作者使用了大量的类比的方法,举例子,进行讲述网络协议世界,我已经看过两遍了,但是,对于非科班出身的来说,没有一点点的基础,还需要再多看几遍,在这里做一下笔记,把好的地方记下来。
一、网络为什么要分层?
我连网络分层都没有听说过,你却问我为什么分层,先搞清楚网络是如何分层的,有一张图片讲述了网络分层,以及每一层所用到的部分网络协议:
网络为什么要分层,因为但凡复杂的程序都是需要分层的,理解计算机网络中的概念,一个很好的切入点就是:想象网络包就是一段Buffer,或者一块内存,是有格式的,同时,想象自己是处理网络包的一段程序,而且这段程序,可以跑在电脑上,可以跑在服务器上,可以跑在交换机上,可以跑在路由器上,你想象自己有很多的网口,从某个口拿进一个网络包来,用自己的程序处理一下,在从另一个网口发送出去,复杂的程序都要分层,这是程序设计的要求。
二、程序是如何工作的?
在专栏中有一张图很形象的讲述了程序工作的大概过程:
文字解析:
(1)当一个网络包从网口经过的时候,你看到了,首先先看看要不要请进来,处理一把。有的网口配置了混杂模式,凡是经过的,全部拿上来。
(2)拿进来之后,就要交给一段程序来处理,于是你调用process_layer2(buffer),当然,这是一个假的函数,但是,其实真实存在着这么一个函数,它的作用就是从buffer中摘掉二层的头,看一看,根据头里面的内容做什么操作。
(3)假设你发现这个包的MAC地址跟你的相符,那就是发给你的,于是需要调用process_layer3(buffer),这个时候Buffer中就没有二层的头了,因为已经在上一个函数在处理过程中拿掉了,或者将开始的偏移量移动了一下,在这个函数里面,摘掉三层的头,看看是发给自己的,还是希望转发出去的,如何判断呢?如果IP地址不是自己的,那就应该转发出去,如果IP地址是自己的,那就是发给自己的,根据IP头里面的标示,拿掉三层的头,进行下一层处理,到底是调用process_tcp(buffer)?还是调用process_udp(buffer)?
(4)假设这个地址是TCP的,则会调用process_tcp(buffer),这时候Buffer里面没有三层的头,就需要查看四层的头,看这是一个发起,还是一个应答,又或者是一个正常的数据包,然后分别由不同的逻辑进行处理,如果是发起或者是应答,接下来可能要发送一个回复包;如果是一个正常的数据包,就需要交给上层了,交给应用去处理了,在四层的头里面,有端口号,不同的应用监听不同的端口号,如果发现浏览器在监听这个端口,那就发给浏览器处理就好了,至于浏览器怎么处理,就与你无关了。
(5)浏览器解析HTML,显示出页面来,电脑的主人,看到页面,点击鼠标,点击鼠标的动作被浏览器捕获,发起另一个HTTP 请求了,于是使用端口号,将请求发送给你(你现在是处理buffer数据包的程序)
(6)你应该调用send_tcp(buffer),不用说,Buffer里面就是HTTP请求的内容,这个请求里面加一个TCP的头,记录下源端口号,浏览器会给你目的端口号,一般是80端口。
(7)然后调用send_layer3(buffer),Buffer里面已经有了HTTP的头和内容,以及TCP的头,在这个函数里面加一个IP的头,记录下源IP地址以及目标IP地址
(8)然后调用send_layer2(buffer),Buffer里面已经有了HTTP的头和内容,TCP的头,以及IP的头。这个函数里面要加一个MAC的头,记录下源MAC地址,得到的是本机器的MAC地址和目标MAC地址,这个是必须要添加的MAC地址。
这样,只要Buffer里面的内容完整,就可以从网口发出去了,你作为一个程序的任务就告一段落了。
三、层与层之间有什么关系?
划重点:只要是在网络上跑的包,都是完整的,可以有下层没上层,绝对不可能没有下层有上层。
所以,对于TCP协议来说,三次握手也好,重试也好,只要想发出去的包,就要有IP层和MAC层,不要是发不出去的,
如果一个HTTP的包跑在网络上,它一定是完整的,无论经过哪些设备,它都是完整的,所谓的二层设备、三层设备,都是这些设备上跑的程序不同而已。一个HTTP协议的包经过一个二层设备,二层设备收进去的是整个网络包。这里面HTTP、TCP、IP、MAC都有,什么叫二层设备啊,就是只把MAC头摘下来,看看到底是丢弃、转发、还是自己留着。什么是三层设备啊,就是把MAC头摘下来,再把IP头摘下来,看看到底是丢弃、转发、还是自己留着。
友情提示:这个专栏真的不错,《趣谈网络协议》