1、引言
整个暑假去面试,面试了很多家公司(无论是小厂还是大厂)问到的深度不同,网络原理是面试最容易问到的问题,虽然我们在项目中很少去实践它,但是了解其原理,会让我们背后网络通信是如果工作的,既能在面试官面前体现出你的基础是否扎实,也能对以后深入网络这部分学习有更多的了解。
很多同学面试在准备这部分的时候,都会去背,这部分确实很难掌握,我个人总结的最好的学习网络原理的方法就是不用刻意的去记忆而是完全的结合实际去讲整个原理融会贯通。虽然一开始学习起来很吃力,但是稍微用点心,多看几遍,多问自己为什么,把自己当做是开发网络原理的开发者,面试前的准备只要理清逻辑就足够了,而不是去背这部分内容。
而且这部分相同的知识点面试官有多种提问方式,但是其中很多都是换汤不换药。我记得最多的问的是输入URL,到页面呈现出来,其中经历了什么?这道面试题的背后,涉及到了很多网络原理的知识,我们这篇文章不会全部分享到,而是先把由来和网络层次划分弄清楚,就完成了这篇文章的目的。
(本文同步发布于:http://www.52im.net/thread-2851-1-1.html)
相关文章:
《网络编程懒人入门(一):快速理解网络通信协议(上篇)》(* 力荐)
《网络编程懒人入门(二):快速理解网络通信协议(下篇)》(* 力荐)
学习交流:
- 即时通讯/推送技术开发交流5群:215477170[推荐]
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
2、关于作者
小鹿(前端工程师):
微信公众号:小鹿动画学编程
Github地址:https://github.com/luxiangqiang
3、系列文章
本文是系列文章中的第7篇,本系列大纲如下:
《脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手》
《脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?》
《脑残式网络编程入门(三):HTTP协议必知必会的一些知识》
《脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)》
《脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?》
4、为什么要进行网络层次划分?
说到网络层次划分并不陌生,我刚刚接触到网络层次的时候一脸懵逼,这么多层,一层不就行了嘛?层与层之间好多协议,还有各种数据包,第一次我放弃了。
当我从新拾起网络层次的时候,我下定决心从根上理解它。首先弄明白它的原理,那必定要知道它的由来,也就是为什么要进行网络层次划分?这个问题问的好。
假如“小鹿”是网络的开发人员,起初认为计算机与计算机之间的通信只需要一根线就可以完成通信,对没错,但是世界那么大,那么多计算机,距离又远,不但浪费线,还没出现各种线被你偷偷剪断的情况,毋庸置疑,那计算机之间通信就不行了。(后边出来了无线网,虽然其中网关、路由之间也需要连线,但不是让每台计算机两两连接,而是一个区域为单位计算机相互连接通信)
不行,老板说,“小鹿”你给我想法子改,改不出来今晚不能睡觉,“小鹿”仔细想了想,这还是个技术活,需要进行全面的改进,也发现所谓的计算机之间的连线只能传送0、1信号,另一台计算并不知道那么多0、1代表什么,而且“小鹿”又发现不同厂商的生产的计算机既然有连线实现通信也是很麻烦的,干脆定义一套规则吧,无论“某硕”计算机还是“某想”计算机,都必须遵守这套规则,其实所说的这套规则就是我们经常说的“网络协议”。
不是说网络层次的由来吗,怎么讲到网络协议了。咱们继续,通过上面的问题,那个计算机之间通过连线传送0、1信号的问题虽然规定了通信规则,但是除了像0、1这种无意义的信号之外,网络中还存在着其他各种各样的问题,两个计算机之间怎么进行识别?以及怎么才能知道对方的地址?以及不同计算机应用程序怎么知道是给自己传递的数据,还有不同的通信数据格式怎么来规定等等一系列的问题都出来了。
“小鹿”发现,如果各种问题都写成一套协议来规定双方通信的规则,但是呢?万一其中哪些规则通信中出现问题,影响到了其他规则,最常见的就是数据包,一个数据包中如果包含各种各样的协议,不就乱套了。
“小鹿”为了能够把它设计的更好,决定采用分层划分的结构,既能规定不同层的完成的功能,又能实现层与层之间的改动而不相互影响,这就是我们经常听到网络划分层次的好处。
5、网络分层是如何进行分层的?
既然我们决定要分层,那么分为几层才好呢?
起初网络分层是标准的七层,也就是我们所说的 OSI 七层模型。
▲ OSI参考模型或七层模型
我们所知道的还有 TCP/IP 四层模型和 TCP/IP 五层模型。这又是怎么出来的,其实所谓的 TCP/IP 四层模型和 TCP/IP 五层模型是以 OSI 七层优化而来,把某些层进行合并了,其实本质上还是相同的,但是我个人最喜欢用五层来解释。
▲ 五层模型
6、每一层的作用是什么?
这一部分涉及到每一层的很多协议和知识点,但是我们这一节不具体分享,为什么?我们具体深入之前必须大脑里有个具体的网络分层结构图,先要知道每层是做什么的,层与层之间的关系,然后下一节再深入每层中的每个协议怎么通信的,这样的好处学起来条理清晰,而不至于当时我学习的时候表面还不懂,就深入最后懵逼状态。
6.1 物理层
物理层,顾名思义,用物理手段将电脑连接起来,就像我们上边讲到的计算机之间的物理连线。主要用来传输0、1信号,上边也分析过了,0、1信号毕竟没有任何的现实意义,所有我们用另一层用来规定不同0、1组合的意义是什么。
6.2 数据链路层
下层的物理层既然不能规定不同0、1组合的信号代表什么意义,那么我们在数据链路层规定一套协议,专门的给0、1信号进行分组,以及规定不同的组代表什么意思,从而双方计算机都能够进行识别,这个协议就是“以太网协议”(具体的以太网协议内容下节内容详细讲解)。
但是问题又来了,我们要发送给对方计算机,怎么标识对方以及怎么知道对方的地址呢?
6.2.1)MAC 地址:
我们所说的MAC地址到底的作用是啥?说白了它就是作为网络中计算机设备的唯一标识,从计算机在厂商生产出来就被十六进制的数标识为MAC地址。
既然我们知道了用MAC地址作为标识,那么怎么才能知道我们要进行通信的计算机MAC地址呢?
6.2.2)广播:
这里广播详细的在下一节讲,这一节你只需要知道广播可以帮助我们能够知道对方的 MAC 地址。那么既然知道了MAC地址就可以通信了?没有想得那么简单,广播中还存在两种情况,一种是,在同一子网络下(同一局域网下)的计算机是通过 ARP 协议获取到对方 MAC地址的。不同自网络中(不同局域网)中是交给两个局域网的网关(路由器)去处理的。这里边涉及到很多细节的知识,都会集中到下一节,但是这一节你了解怎么进行标识计算机和怎么获取到MAC地址就可以了。
6.3 网络层
物理层和数据链路层都有自己的事情要做,也就是我们上边所讲到的这些(里边很多细节不在这节多说)。上边两层在我看来可以完成正常通信了,那么网络层出来干啥子?
网络层的由来是因为在数据链路层中我们说说两台计算机之间的通信是分为同一子网络和不同子网络之间,那么问题就来了,怎么判断两台计算机是否在同一子网络(局域网)中?这就是网络层要解决的问题。
6.3.1)IP 协议:
我们通常用到的 IP 地址,就是网络层中的东西,所规定的的协议就是 IP 协议。很多小伙伴问,IP 地址想必也是地址吧,上边都有唯一标识的 MAC 地址了,IP 地址出来是混饭吃的?为了能够让大家更方便的理解 IP 地址和 MAC 地址,我们可以将 IP 地址抽象成一种逻辑上的地址,也就是说 MAC 地址是物理上的地址,就是定死了。IP 地址呢,是动态分配的,不是固定死的。
我们就是通过 IP 地址来判断两个计算机设备是否在同一子网络中的,那么你会问它是怎么判断的,以及 IP 地址谁给他分配的?又是如何分配的等一些列问题,我们不着急,这里只说一下大体的流程,详细会后续写一大篇。
既然我们通过 IP 地址来判断两个计算机是否处于同一局域网中,那么首先要知道对方的 IP 地址吧?DNS 解析想必大家都知道,可以将域名解析为 IP 地址。好了,我们知道两台计算机的 IP 地址了,怎么进行判断是否同一局域网中?
6.3.2)子网掩码:
嘿嘿,又是一个只听说过,但是不知道这个什么作用的一个名词,没事,等我聊完,你就明白是做什么的了。
子网掩码就是用来标识同一局域网中的 IP 地址的信息的?什么信息?IP 地址是由 32 个二进制位组成的,也就是四个十进制(如:255.255.255.000)。
子网掩码也是由 32 个二进制位组成的,但是只能用 0 或 1 来表示,如:11111111.11111111.11111111.00000000。
到底什么意思呢?有 1 的部分表示网络部分,有 0 表示主机部分,这和判断两台计算机是否在同一局域网中有什么关系?没错,是有关系的!两台计算机的 IP 地址分别和子网掩码进行一种运算(AND 运算),如果结果相同,两台计算机就在同一局域网中,否则就不在同一局域网中。
AND 是如何进行运算的,IP 的数据包的组成等问题,不在这里多陈述。
6.4 传输层
好了,如果你认为计算机可以进行通信了,那么“小鹿”恭喜你,你已经基本知道了以上几层划分的作用,但是如果你正在一边打 LOL,一边和朋友在 QQ 聊天,突然,游戏中队友聊天信息出现在了 QQ 窗口中,咦?出现了什么情况?
其实是以上层级还是不够,出现上边的原因就是,两台计算机虽然可以通信了,但是每天计算机运行着好多的程序,谁知道你们传输的信息是属于哪些程序的,怨不得 LOL 的聊天信息跑到了 QQ 窗口中。
想必大家猜到了传输层主要用来干啥滴,是的,传输层的主要功能就是为了能够实现“端口到端口”的通信。计算机上运行的不同程序都会分配不同的端口,所以才能使得数据能够正确的传送给不同的应用程序。
6.4.1)UDP 协议:
加入端口号也需要一套规则,那就是 UDP 协议,但是 UDP协议有个缺点,一旦进行通信,就不知道对方是否接收到数据了,我们再定义一套规则,让其可以和对方进行确认,那么 TCP 出现了。
6.4.2)TCP 协议:
我们通常说 TCP 三次握手和四次挥手,没错,这就是传输层中完成的,TCP 三次握手涉及到的内容贼多,都可以单独写一篇长文,这里不多陈述,知道它是在传输层中完成的以及它的作用是什么,能够认识到它就好了。
6.5 应用层协议
“喂,你发给我的是什么破数据,乱七八糟的,我TM能解析吗?能不能按照我的规定给我传送?“
“好的,下次不敢了”
想必大家已经猜到了应用层的协议,应用层的功能就是规定了应用程序的数据格式。我们经常用得到的电子邮件、HTTP协议、以及FTP数据的格式,就是在应用层定义的。
7、每一层的的功能细节是什么?
前面章节主要分享了网络分层的基本概念,为什么要进行网络分层?又是如何进行分层?每一层的基本功能是什么?而且对于每一层的的功能细节方面,比如数据包的组成以及每层包含的一些协议的使用都没有细说,那么本节将继续分享网络分层每层中协议等深入讲解。(PS:可能里边有的讲解不正确,还请大佬指出改正)
7.1 物理层
物理层里边涉及到最多的是硬件底层的一些内容,没有需要过多了解的内容,我们直接看数据链路层。
7.2 数据链路层
上回讲到数据链路层中规定的“以太网协议”来规定电信号的分组形式,什么是以太网,以太网的数据包是什么样子的?
7.2.1)以太网协议:
以太网规定,每组的电信号就是一个数据包,每个数据包我们可以成为“帧”。每帧的组成是由标头(Head)和数据(Data)组成。
那么你会问,标头里有什么信息?Data 数据又会存放写什么?为什么分为两部分?放在一块不好吗?
a)标头:
为什么传输数据会有标头,我们想呀,在传输数据的时候,接收端怎么判断是不是给自己发送的,那么就只取出标头来进行判断。
数据包的标头中通常会存放一些有关数据包的说明、发送者是谁、接受者又是谁等相关识别信息。
标头的长度固定为 18 字节,也就是说,一些标头识别信息的大小不能超过 18 字节。
b)数据:
数据,顾名思义,你要传输给接收端什么数据都会放到数据包中,也就是整个数据包的具体内容,比如文件、字符串之类的。
数据部分的长度最小至少为 46 个字节,最长 1500 字节。我们可能会想到,如果小于 46 字节没啥问题可以存放开,那么大于 1500 字节怎么处理呢?很简单,我们就分成两个包处理(分割),两个包存放不下就分割成三个包…
7.2.2)广播:
上回说到,广播的作用就是用来查找接收端的 MAC 地址,从而进行下一步的数据传输。注意,广播只是一种发送数据的形式,而计算机想要知道另一台计算机的 MAC 地址是通过 ARP 协议解决的,ARP 协议会在讲完 IP 协议后再说,因为它会涉及到 IP 协议的一点内容,现在讲可能会有点乱。
如果你觉的上边稍微有点乱,那怎们稍微屡一下,我们想要发送数据,首先要知道对方的唯一标识(MAC 地址),要想知道对方的 MAC 地址,需要使用 ARP 协议,假设我们通过 ARP 协议拿到了接收方的 MAC 地址。
我们开始发送数据,将发送方的 MAC 地址和接收方的 MAC 地址封装在数据包中,然后发送端向同一子网络中(同一局域网)中的所有计算机发送该数据包,所有的计算机接收到该包之后,就对数据包的头部进行提取,提取出里边封装好的接收端 MAC 地址和自己的 MAC 地址作比对,如果相同,就说明该数据包是给自己发送的,否则,就会丢弃该数据包,这个过程就是广播的过程。
上一篇文章在这个地方留下的一个问题就以上是在同一局域网中,如果不在同一局域网中我们怎么处理?我们平常使用无线网都知道每个无线局域网都会有一个路由器,我们先通过以上的方法将数据发送到路由器,然后路由器转发数据到其他局域网中的计算机。
7.3 网络层
网络层中最重要的一个协议就是 IP 协议,我们一般发送端给服务端发送数据同时要知道两个地址才能准确送达到对方,分别为 IP 地址和 MAC 地址。停!stop! 上边讲到的明明知道对方的 MAC 地址就可以传输数据了,为什么现在需要两个地址呢?你给我说明白,说不明白取关!
上边确实是一个 MAC 地址就可以通信,但是前提是通过 ARP 协议获得的 MAC 地址,而 ARP 协议正是利用的接收端的 IP 地址才获取到接收端的 MAC 地址的,所以这两个地址很重要,那么如果实现的,下边会继续讲。
7.3.1)IP 协议:
IP 的数据包是直接放入到以太网数据包的“数据”部分的,这样做有一个好处就是“上层的变动完全涉及不到下层的结构”。然后数据包就变成这个样子了。
IP 数据包也分为标头(Head)和数据(Data)两部分:
- 1)标头:IP 数据包的标头是 20 ~ 60 字节,主要包括版本、IP 地址等信息;
- 2)数据:数据的最大长度为 65515 字节。整个 IP 数据包的最大总长度为 65535 字节。主要存放 IP 数据包的具体内容。
问题来了,以太网的数据部分最长为 1500 字节,你把一个长度为 65535 字节的 IP 数据包放到以太网的数据包汇总,不会被撑破吗?你在逗我么?确实是呀,那我们就分割数据包吧,分割成几个以太网数据包分开发送。
7.3.2)AND 运算:
IP 协议上篇文章中最重要的作用就是判断两个设备是否属于同一子网中(同一局域网中)。
将两个IP地址与子网掩码分别进行AND运算(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。
我们可以通过 DNS 解析知道对方的 IP ,除了判断两个计算机是否在同一局域网中,还有一个作用就是然后通过 ARP 协议获取到对方的 MAC 地址。停!真想让我取关吗?ARP 就 TN 的说了多少遍了,该详细说一下了吧?
7.3.3)ARP 协议:
前提:对方的 IP 地址是已知的,通过 DNS 解析得到。
ARP 协议发出一个数据包,包含在以太网的数据包中(其中包含对方的 IP 地址,对方的 MAC 地址栏是 FF:FF:FF:FF:FF:FF)。子网络中的每台主机都会收到这个包,然后从中取出 IP 地址与自身对比,如果两者相同,都做出回复,向对方报告自己的 MAC 地址,否则就丢弃这个包。
7.4 传输层
传输层主要涉及到两个重要协议,UDP 和 TCP 协议,上篇讲过主要用来确定端口到端口的通信,计算机中不同运行的程序端口号不相同。
"端口"是 0 到 65535 之间的一个整数,正好 16 个二进制位。0 到 1023的端口被系统占用,我们只能选用大于1023 的端口。
7.4.1)UDP 协议:
UDP 协议也分为标头(Head)和数据(Data)两部分:
- 1)标头:标头的长度为 8 字节。主要存放了发送和接收端口号;
- 2)数据:数据部分和标头部分的总长度不超过 65535 字节,正好放进一个IP数据包。
前边也讲过,数据包之间是包含关系的,所以 UDP 的数据包是放到 IP 数据包的“数据”部分的,IP 数据包又放在以太网数据包的“数据”部分的。
7.4.2)TCP 协议:
TCP 和 UDP 是相同的,上一篇讲了 UDP 和 TCP 的优缺点,TCP 保证了网络的可靠性,TCP 三次握手和四次挥手就是这部分内容。
TCP 的数据包和 UDP 相同嵌入在 IP 协议的“数据”部分,TCP 并没有长度限制,但是为了保证传输效率,肯定要进行限制的,TCP 的数据包的长度一般不会超过 IP 数据包的长度了,保证单个的 TCP 数据包不再进行分割。
7.5 应用层
应用层是最高一层,直接面向用户,它的数据包会放在 TCP 的数据包的“数据”部分,那么整个五层的数据包就会变成一下这样。
以上五层中的内容基本讲完了,我是从下到上逐层写的,这篇文章可以让你入门网络五层协议的基本内容了。
8、写在最后
如果本文内容看完,还是有点懵,那怎么办?
可以继续以下两篇文章,它们应该可以让你内力倍增:
另外,关于计算机网络协议的分层和关系,可以看看下面两图:
* 上述两张图的清晰原图,请见:《计算机网络通讯协议关系图(中文珍藏版)[附件下载]》。
附录:更多网络编程基础资料
《技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)》
《通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理》
《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》
《P2P技术详解(一):NAT详解——详细原理、P2P简介》
《P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解》
《P2P技术详解(三):P2P技术之STUN、TURN、ICE详解》
《高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少》
《高性能网络编程(二):上一个10年,著名的C10K并发连接问题》
《高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了》
《高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索》
《高性能网络编程(五):一文读懂高性能网络编程中的I/O模型》
《高性能网络编程(六):一文读懂高性能网络编程中的线程模型》
《Java的BIO和NIO很难懂?用代码实践给你看,再不懂我转行!》
《不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)》
《不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)》
《不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT》
《不为人知的网络编程(七):如何让不可靠的UDP变的可靠?》
《不为人知的网络编程(九):理论联系实际,全方位深入理解DNS》
《网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势》
《网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门》
《网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接》
《网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?》
《网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议》
《技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解》
《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障》
《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
《移动端IM开发者必读(二):史上最全移动弱网络优化方法总结》
《从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路》
《以网游服务端的网络接入层设计为例,理解实时通信的技术挑战》
《全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等》
《美图App的移动端DNS优化实践:HTTPS请求耗时减小近半》
《Android程序员必知必会的网络通信传输层协议——UDP和TCP》
《IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)》
《IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)》
《IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁》
《IM开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史》
《IM开发者的零基础通信技术入门(五):1G到5G,30年移动通信技术演进史》
《IM开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术》
《IM开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”》
《IM开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲》
《IM开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”》
《IM开发者的零基础通信技术入门(十):零基础,史上最强5G技术扫盲》
《IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!》
《IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!》
《IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!》
《IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!》
《IM开发者的零基础通信技术入门(十五):理解定位技术,一篇就够》
《百度APP移动端网络深度优化实践分享(一):DNS优化篇》
《百度APP移动端网络深度优化实践分享(二):网络连接优化篇》
《百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇》
《可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?》
>> 更多同类文章 ……
(本文同步发布于:http://www.52im.net/thread-2851-1-1.html)