带着4个问题学习:
1.TCP在进行三次握手的时候,IP层和MAC层对应都有什么操作呢?
2.学习第三层的时候会提到,IP协议里面包含目标地址和源地址。第三层往往还会学习路由协议,路由是中转站,我们从原始地址A到目标地址D,中间经过两个中转站A->B->C->D,是经过路由转发的。
那么,A知道自己的下一个中转站是B,应该把B的IP地址放在哪里呢?B知道自己的下一个中转站是C,从B发出来的包,应该把C的IP地址放在哪里呢?如果放在IP协议中的目标地址,那包到了中转站,怎么知道最终的目的地址是D呢?
3.经常听说二层设备,三层设备。二层设备处理的通常是mac层的东西,那我发送一个HTTP包,是在第七层工作的,那是不是不需要经过二层设备?即便经过了,二层设备是否处理?或者说,二层设备处理的包里,有没有HTTP层的内容?
4.综合问题。从你的电脑,经过ssh登陆到公有云主机里,都需要经历哪些过程?
网络为什么要分层?
复杂的程序都要分层,这是程序设计的要求。比如:复杂的电商还会分数据库层、缓存层、compose层、controller层和接入层,每一层专注做自己本层的事情。
程序是如何工作的?
当一个网络包从一个网口经过的时候,你看到了,首先要看看要不要请进来,处理一把。有的网口配置了混杂模式,凡事经过的,全部拿进来。
拿进来之后,就要交给一段程序处理。于是,你调用process_layer2(buffer)。当然,这是一个假的元素,你知道有这个函数。
这个函数中,摘掉二层的头,看一看,应该根据头里面的内容做什么操作。
假如mac地址与自己的相同,那证明是这个包是发给自己的,于是调用process_layer3(buffer)。这个时候,buffer里面已经没有二层的头了,因为在上一个函数中处理的过程已经拿掉了,或者将开始的偏移量移动了一下。在这个函数里,摘掉三层的头,看看到底是发给自己的,还是希望转发出去。
如何判断呢? 如果ip地址不是自己的,就转发出去,如果ip是自己的,那就是发给自己的。根据ip头里面的标示,拿掉三层的头,进行下一层的处理,到底是调用process_tcp还是process_udp呢?
假设这个地址是tcp的,则会调用process_tcp(buffer).这时候buffer里面没有三层的头,就需要查看四层的头,看这是一个发起,还是一个应答,又或者是一个正常的数据包,然后分别由不同的逻辑进行处理。如果是发起或者应答,接下来可能要发送一个回复包;如果是一个正常的数据包,就需要交给上层了。交给谁呢?是不是有process_http(buffer)呢?
没有的,如果你是一个网络包处理程序,你不需要process_http(buffer),而是应该交给应用去处理。交给哪个应用呢?在四层的头里面有端口号,不同的应用监听不同的端口号。如果发现浏览器应用在监听这个端口,那你发给浏览器就行了。至于浏览器怎么处理,和你没有关系哦。
浏览器自然是解析HTML,显示出页面来。电脑的主人看到页面很开心,就点了鼠标。点击鼠标的动作被浏览器捕获。浏览球知道,又要发起另一个HTTP请求了,于是使用端口号,将请求发给你。
你应该调用send_tcp(buffer).不用说,buffer里面就是HTTP请求的内容。这个函数里面加一个TCP的头,记下源端口号。浏览器会给你目的的端口号,一般为80端口。
然后调用send_layer3(buffer).buffer里面已经有HTTP的头和内容,以及tcp的头。在这个函数里面加一个ip的头,记录下源ip的地址和目标ip的地址。
然后调用send_layer2(buffer)。buffer里面已经有了HTTP的头和内容,tcp的头,以及ip的头。这个函数里面要加一下Mac的的头,记录下源mac地址,得到的是本机器的mac地址和目标mac地址。不过,这个还要看当前知道不知道,知道就直接加上;不知道就通过一定的协议处理过程,找到mac地址。反正要填一个,不能空着。
万事具备,只要buffer里面的内容完整,就可以从网口发出去了,你作为一个程序的任务就算告一段落了。
揭秘层与层之间的关系
知道了这个过程之后,我们再来看一看原来困惑的问题。
首先是分层的比喻。所有不能表示出层层封装含义的比喻,都是不恰当的。
总经理握手,不需要员工在吧,总经理之间谈什么,不需要员工参与吧,但是网络世界不是这样的,。正确的应该是,总经理之间沟通的时候没,经理将总经理放在自己兜里,然后组长把经理放自己兜里,员工把组长放自己兜里,像套娃一样。现实生活中,往往是员工说一句,组长补充两句,经理补充两句,总经理补充两句。在网络时间里,则是相反的。
那TCP在三次握手的时候,ip层和mac层在做什么呢?当然是tcp每发送一个消息,都会带着ip层和mac层了。因为tcp每发送一个消息,ip层和mac层的所有机制都要运行一遍。而你只看到了tcp3次握手,其实,ip层和mac层也忙活了很久。
这里要记住一点,只要是在网络层上跑的包,都是完整的。可以有下层没上层,绝对不可能有上层没下层。
所以,对tcp协议来说,3次握手也好,重试也好,只要想发出去包,就要用ip层和mac层,不然是发不出去的。
经常有人问,我都知道那台机器的ip地址了,直接给他发消息呗,干嘛还要mac地址。 这里的关键是,没有mac地址消息是发不出去的。
所以如果一个HTTP协议的包跑在网络上,他一定是完整的。无论这个包经过哪些设备 ,他都是完整的。
所谓的二层设备、三层设备,都是这些设备上跑的程序不同而已。一个HTTP协议的包经过一个二层设备,二层设备收进去的是整个网络包。这里面HTTP,TCP,IP,MAC都有。什么叫二层设备呀,就是只把mac头摘下来,看看到底是丢弃、转发、还是自己留着。那什么是三层设备呢?就是把mac头摘下来之后,再把ip头摘下来,看看到底是丢弃、转发、还是自己留着。
小结:
1.始终想想自己是一个处理网络包的程序:如何拿到网络包,如何根据规则进行处理,如何发出去
2.始终牢记一个原则:只要是在网络上跑的包,都是完整的。可以有下层没上层,绝不可以有上层没下层。