作者:手机用户3312丿075454 | 来源:互联网 | 2023-01-12 10:13
目录
- Intro&物理层
- 数据链路层
- 网络层
- 传输层
- 详解TCP/IP
- DNS
- 详解HTTP
- LVS/Nginx 负载均衡
Intro
作为程序员,我们往往只关注OSI模型的上层应用部分;编写的接口通常都是Restful接口或者直接用TCP传输完整对二进制内容,很少了解底层原理,这就导致遇到网络问题时不知如何下手,无法分析出问题的本质;也造成了很多误解。本文将带你自底向上了解网络传输对原理,OSI模型中对每一层负责什么功能。
首先要推荐Ben Eater的这个视频教学:Networking tutorial ,从底层到应用讲的极为清楚,看了这个系列视频使我对网络基础恍然大悟。本文很多内容都是视频里所讲解的。他的其他视频例如8-bit计算机的原理,也非常精彩!
常见误区
首先说一个最常见的误解,例如我们经常看到这样的图:
这个图本身是讲OSI模型的对等性,每一层发送的数据,以相同层去接收的时候,获得的数据是一模一样的。但是我们可能会误以为每一层与每一层是独立交互互不影响的,其实不然,每一层在发送或接收数据时都是调用了下一层一协议。
OSI模型如同我们做项目时把庞大的项目分项目分模块一样,是把网络传输这种复杂的功能分成了不同层,每一层完成不同粒度的功能,每一层提供统一接口供上层调用。这么做让不同层对协议可以互相兼容,有了规范就可以实现很好对复用了。
例如我们在浏览器里输入一个网址,完成的调用过程是这样的:浏览器把我们的地址封装成一个HTTP(7层)报文->HTTP调用TCP建立TCP连接(4层)-> TCP调用IP协议,把目标地址加到IP协议(3层)头上->IP协议调用Ethernet协议,把目标的MAC地址加到Ethernet协议(2层)头上->Ethernet协议调用网卡的硬件接口,把二进制数据写入网卡(1层)->网卡根据所接的网络速度,把二进制数据变成可以在网线上传输的数字信号,发给目标机器。
而服务器的网卡(1层)接收到数字信号,解析成二进制数据,逐层向上传递,上层逐层解析。最后服务器的HTTP服务(7层)拿到了请求,将用户需要的内容回发给用户(又是一次完整的从7层至1层调用,从1层至7层解析的过程)。
也就是说,我们理解OSI模型时,需要按如下这种图理解:
推荐一个完整的OSI模型涉及协议的图(图片来源:http://www.colasoft.com.cn/download/protocols_map.php)
请在新标签中看大图
好啦,下面我从物理层开始,逐层讲一下每一层负责什么,每一层的协议是如何解决传输问题的。
物理层
物理层解决的是最基本的二进制传输问题
例如小明要给小丽传输一个字符‘A’,如何传递呢?
我们都知道计算机使用的是数字信号,只有1和0,而1和0在计算机里是用高电平(可理解为有电)和低电平(可理解为没电)表示。例如小明在一个屋子里,有一个开关,可以控制另一个屋子里的灯泡;小明按下开关,导线通电,小丽所在的屋子里灯泡亮了,这就可以用来表示1,小明松开开关,小丽看到灯泡灭了,表示了0。这样小明就能给小丽传输1和0了。
计算机传递数字信号也是一样的道理,只要通过导线传递高低电平就可以了。
为了解决文字用二进制数据的表示,产生了ASCII码,A用ASCII码表示成二进制的值是:01000001
计算机发送数字信号,传输‘A’的过程,如果我把导线高电平和低电平的随时间变化用画成图来表示,就是如下这样子:
但是如果计算机收到来这个信号,他是否能成功解析成01000001呢?
不好说,因为很容易把同样的信号解析成0100001:
丢了一个0!
异步串口协议
第一种方案:为了解决这个问题,前辈们发明了时钟这个概念;例如速率为115200b/s的数据传输协议,每一位数据的周期约为8.6uf,在接收端使用与发送端相同的频率接收,即可获得完整的数据。(这就是异步串口协议AsyncSerial)
右侧的是串口卡,通常用来调试嵌入式设备,比如老式的摩托罗拉手机。左侧是逻辑分析仪,可以捕获数字信号。
如图我用串口芯片发送了一个‘A’,与ASCII码对应,传输速率(Sample Rate)是11520bit/s(新标签看大图)
但是网络传输速率很快,我们平时接触到的最慢网卡速率也是10Mb/s的,每一位的信号占用100ns的时间(100Mb/s网卡一位用10ns,我们现在电脑的标配有线网卡都是1000Mb/s的,也就是每一位传输用1ns),在这么快的速度,两个计算机的时间稍有误差一点点,数据就不对了!
同步串口协议
第二种方案,添加一条单独的时钟线。时钟线每一个采样发送一个由低电平到高电平的脉冲,接收端在收到时钟线的脉冲的同时去读数据线,这时数字线如果是高电平就是1,低电平就是0。这种方案在高速传输时是没有问题的。如下图所示:
第一条线是时钟,第二条线在此处忽略,第三条线便是数据,每次时钟触发读数据的操作。此处不详细解释这个协议。
那么这种方案可以用于网络传输码?答案依然是否定的,因为由于网络传输距离很长,几百米是常事,并且速率很高,由于线材的电容和电感会导致信号相位产生变化,也一样会导致数据传输错误。
物理层协议10BASE-T
而实际在网络传输过程中,物理层协议10BASE-T(10M网卡)规定所定义的编码方式是曼彻斯特编码,曼彻斯特编码把时钟和信号合在了一起,使用高到低的电平跳变表示1,用低到高的电平跳表表示0,实际信号是这个样子的:
视频中用示波器捕获网线上的发送线信号,物理层协议T568B(即我们平时用的网线,里面有八根线),橙和橙白是一对,用来数据发送。种协议数据里自带频率,网卡可以很准确对识别出数据。
信号的起始是这样的:
这时我们根据曼彻斯特编码来解析这段信号:
这样0和1组成的二进制数据就完美的传输了。
百兆协议100base-t使用4B/5b编码,千兆协议1000BASE-T使用8B/10B编码,更适合高速传输,在此处不再详细描述了。
所以说物理层所定义的不仅是物理设备,网线里有几个芯,网线头什么尺寸。最主要定义的是怎么保证二进制数据稳定传输。物理层定义的内容会直接在网卡里由硬件实现,网卡芯片向上对数据链路层提供完整对二进制数据,数据链路层不需要考虑10M/100M/1000M/光线网卡具体怎么传输二进制,一个数据链路层协议接哪一种物理层协议都是兼容的,因为接口是固定的,即二进制数据。
下节课讲数据链路层Ethernet协议,我再讲这一连串的1和0代表着什么。
thanks :)
(转载请注明出处:http://blog.wkgeek.com)