从订外卖的角度来理解- 一个网页是如何到你手上的。

我们先来想像这么一个场景:

有一个名字叫做linux美食城 ,  然后这个美食城的80号店铺 名字叫做Apache ,你进入店中 , 服务员立马递给你一个菜单index.html  

然后你开始浏览菜单,你发现菜单上有两种菜系,一种是川菜(后缀php)  ,另一种是粤菜(后缀jsp) 。

 接下来你开始点菜了,  你想吃一道川菜:麻婆豆腐.php    还想吃一道粤菜:盐焗鸡.jsp  


 你点好单后,服务员拿到了你的菜单, 他看到你点了一个后缀为php的菜, 在他的记忆中(httpd.conf文件)里面 记录了一条 关于php后缀该怎么做的,上面写道:php=>php7.0 于是 他知道要把这道菜告诉名叫php7.0厨师  厨师看到了,就从冰箱(数据库)里拿出 豆腐,葱花(网页上要显示的数据,例如你的个人信息) 等等的食材开始进行烹饪处理。  同样的 服务员也把盐焗鸡.jsp的请求  提交到后厨的 Java厨师那  于是厨师也从冰箱(数据库)里取出食材来处理  
 
 当麻婆豆腐.php 做好了, 服务员就从php7.0 那拿过来 上桌。 jsp同理。
 到这里 就简单完成了对动态网页的请求了。
 那么 与静态网页的区别是什么呢?  
 
 同样是这家店,你刚刚点的菜是小炒, 这个时候,你看见菜单上有道凉拌菜叫凉拌黄瓜.html  你把服务员叫过来,点了这道菜。  他一看 是个快餐(静态网页)  于是就去后厨快餐柜里取出了这道菜 直接上桌,  当初开发人员早就做好的这道菜,就原原本本的上菜了,不经过任何处理。 这就是静态网页访问。
 
 好了,后台处理的原理,我们大概了解了。。 那么我们访问一个网页,肯定不需要真真正正的来到这家店里啊。不然你逛淘宝就得买个机票去浙江咯?  
 还记得开始我们说过 这家店是linux美食城80号店铺吗, 相当于他在这个linux系统中监听了80端口 于是他只做分内的事情 只处理来访第80店铺的客人(只处理80端口的请求)
 
 现在,我就想在家就吃到这家店的菜,我们可以订外卖啊,,那么订外卖就是一个请求。  
 我们首先要知道要打电话给谁?  肯定是打电话给这个美食城啊,可是我们不知道这个linux美食城的电话号码(IP地址)  我们就先打电话给114电话查询台(DNS服务:114.114.114.114
 你跟114的说:我要打电话给linux美食城  114查了他所维护的一个电话本,查到linux美食城的电话号码:119.75.217.109 然后我们知道了美食城的号码咯。 
 接下来 我们就拨通linux美食城的号码:119.75.217.109    不一会有人接了, 你对话筒说: 请帮我接通80号店铺,,这时,你的电话就已经拨通到Apache的座机上了。
 
 还是这个服务员:你好 请你看看我们的菜单index.html  你还是点了这两个菜  麻婆豆腐.php 盐焗鸡.jsp   。店里还是那样忙碌,,两位大厨做好之后,不一会 外卖小哥就把你点的菜 送到了你的家里。
 
 好了,到这就是我们基本HTTP访问流程了     我们真实网络的数据肯定不是像打电话那样的语音方式了。
  那么我们把刚刚那些打电话环节都换成写信, 你写的信就是所谓的数据包
  这里就引入了我们的网络七层结构, 为了简单起见 我们先使用比较广义的网络五层结构  
  自顶向下
分别是 应用层>>传输层>>网络层>>数据链路层>>物理层   
  每层的工作都不同,上一层是需要依赖下一层的工作的。 就好比现在你用电脑办公 你需要依赖电厂发电你才能够开机。
  先讲应用层 : 他就是我们平时常见的各个服务 HTTP DNS  FTP P2P 之类的  
  像访问一个www服务的网页,就要用到HTTP协议,那么这个协议的东西又是由HTTP服务提供的比如前面提到的Apache
那么什么又是协议呢?  其实协议就是由开发人员制定出来让大家互相之间能够交流的通讯约定。  
比如 我们要点菜,你就开始写信:
{我,秦始皇,盐焗鸡。}


虽然稍微有点灵性的人应该看得出来 点的菜是盐焗鸡。 可是,机器是很笨的,说不定,他认为我们想要吃秦始皇。。 
那么我们就做了点工作  制定了一个协议HTTP  规定你先写你的行为,然后跟上个内容 最后跟上个协议版本号 比如:
{get /盐焗鸡.jsp  HTTP/1.1}
这样 我们的机器就知道我们想要get一个盐焗鸡.jsp协议版本号是1.1 是现在使用的。 双方好理解

这样确保了我们的交流是正确的。


好到这里我们稍微理解了一点协议作用 以及稍微懂了点HTTP协议怎么写  我们回到刚刚应用层


你要订外卖,开始写信 使用的是HTTP协议写的,为的就是让linux美食城里面的Apache餐馆也能看得懂。 内容如下:
{get /麻婆豆腐.php HTTP/1.1 }


可是我们不知道地址在哪啊?(上面的电话地址是另一个平行时空,我们重开新存档) 那么就需要问一下查一下类似114的查询组织了。 也就是说我们需要先写信DNS服务器查到我们目标地址 但是DNS服务又是使用另一个协议了:DNS协议   (什么,你说我们也不知道DNS的地址? 其实我们对电脑配置网络的时候已经配置了DNS地址了。 或者你设定成自动获取了。 就像我们都知道114是电话查询台一样)
我们这么写:
{Standard query 0xf7fb A linux美食城.com}  
我们假定美食城的根域名com 
信中:
Standard query  告诉DNS我们要进行标准查询 
0xf7fb 一个查询标识符,如果我们同时进行四五个查询的话 我们就用一个记号来标出哪个结果是哪个查询的。 不然都认不出来
A 告诉DNS我们想要一个ipv4地址查询
linux美食城.com 我们想要查询的东西


我们把信发出去后收到了一个回信:     (这里涉及到的向下层传递数据的 我们留到后面再讲)
{Standard query response 0xf7fb A 119.75.217.109}
这里呢Standard query response 告诉我们是个响应
0xf7fb 告诉我们这个的响应是对应我们之前那个查询的
A 是个ipv4 地址
119.75.217.109  后面就是我们想要知道的内容了。


到这里 我们已经知道了地址了 接下来我们就要把刚刚写好的点菜的信包装起来了
为什么要包装呢? 写完信了当然要信封包装起来 然后在信封上写上地址  送信的才会知道要送去哪里啊。
这里我们就要用到传输层的东西了。。传输层是做什么的?  他是提供两个端到端缓冲, 好比我们家门牌号是4396号(4396端口),目的店铺是80号(80端口)。

那么这里我们就要把我们的信放进一个tcp数据包里  为了易于理解 现在我们规定一个简单的tcp协议为:

{源端口  目的端口 {数据}}

我们就要这样把我们的信打包好成一个数据包
{4396  80 {get /麻婆豆腐.php HTTP/1.1 }}
一个简单的tcp数据包就做好了 


像刚刚我们对DNS进行地址请求的时候 也是打包成了一个udp数据包平时DNS查询都是使用udp协议的,当然你也可以使用tcp协议 ,现在我们假装协议类似 那么就可以这样打包
{4396  53 {Standard query 0xf7fb A linux美食城.com}}
53端口是DNS服务的端口号
一个简单的用于请求的地址的udp数据包就做好了  他就得发送给DNS服务器


可是地址还没写呢! 别急 这就是网络层的东西了 
网络层 我们要把上层交给我们的tcp数据包 再次进行包装,然后给他包装的头部再加上ip报头  这样就能指示出数据的去向了

我们现在来定义一个简单的ip报头 

{总长度  协议类型  源地址  目的地址}

总长度表示出了这个包的长度,为什么需要这个呢?  因为网络世界不像现实世界那样看得到数据的边界 我们一封信拿在手上就是个完整的。但是在网络里面,是由电进行传输的,除了高电压就是低电压 相当于二进制的‘1’和‘0’  而且通讯是持续的,机器没法看到数据的边界,就不知道这封信的内容是否接收完了。  所以我们要一个总长度 让机器接收够一定数量的二进制数据之后 就划分开。 那么这就是个完整的数据包了。


协议类型 1 ICMP    2 IGMP    6 TCP   17 UDP   88 IGRP   89 OSPF   表示出所携带的数据协议是什么协议?
源地址    寄信人的地址 
目的地址   收信人的地址


好 现在我们开始对我们的tcp包进行打包
{33  6  192.168.1.2   119.75.217.109 {4396  80 {get /麻婆豆腐.php HTTP/1.1 }}}
这里33是我们的数据包的长度  6表示我们的数据包是tcp数据包, 
这里的源地址192.168.1.2 是个内网地址,就是假设我们现在使用的是一个路由器了,处在了路由器内网里,送过去后对方怎么得知我们在哪的? 这里注意一下 这个技术就需要用到网络地址转换技术了(NAT,Network Address Translation) 简单来说就是路由器的网关把你的信拦下来了,然后 把我们的源地址 改成了公网地址123.231.132.111这样的地址。 就相当于 我们一开始 我们分配到的地址其实是内网地址--小区地址  二栋.二单元.四楼.4396房 ,信件经过路由器网关(看门大爷)他有个职责就是把地址转换成公网地址 123.231.132.111  这样别人就能知道我们确切位置了  当然NAT可不那么简单,我们以后再讲。 现在回来
目的地址写上了我们之前用DNS查询到的地址,就是linux美食城的地址。


好,做了充分准备了。该送信了>>>>>>>>>
数据链路层 ----  一个敬业的邮递员  他不会拆开数据包 也不验证你的数据包是不是有错误。他就只管送   

邮递员走哪条路,绕哪条路其实是上一层网络层里的路由选择协议 可是为了简单我们现在就不探讨那些复杂的路由选择协议了。


 那么邮递员也是需要下层的支持啊   物理层>>>>>
 所谓物理层,就是我们主机怎么接入网络的,管理物理层用的光纤还是电话线 它的上层都不管,每个层做好份内的事情就好了。
 那么物理层我们可以想象成是我家到linux美食城马路  这样邮递员就能够骑着他的小电驴 往返于我们之间了
 
好,简单的自顶向下之后。 我们的数据包送到了 linux美食城的门卫手里  这里 ip包装被剥开了,
门卫手上只剩下tcp数据包{4396  80 {get /麻婆豆腐.php HTTP/1.1 }}
他一看 80号店铺  就放在了门卫室(网卡)80号收件箱里  这里也剥开了tcp的包装 只剩HTTP信件内容{get /麻婆豆腐.php HTTP/1.1 }
每隔一段时钟周期,都会有不同店铺的人来取信件,
80号店铺的人来了,拿走了堆积在80号收件箱里的所有HTTP数据包
回到店里 ,各位大厨开工啦!!  
不一会 麻婆豆腐.php 做好了。 
又开始新一轮的打包  这里就是我们的HTTP响应数据包了 简单定义HTTP响应报头{HTTP/1.1 200 OK  响应正文}
这里HTTP/1.1 一个HTTP协议版本号 
200  HTTP协议状态码  200 相当于正确响应‘OK’  常见的404 “页面找不到”  这个三位数都是可辨识的, 2xx 都代表成功响应  3xx 大多指重定向 4xx 代表请求错误 5xx代表服务器错误 服务器错误就是那家店出问题了。。比如鸡肉拿错成了猪肉了等等、 请求错误就是你发出的请求错了,你请求冰淇淋 店里不卖冰淇淋 只能返回404
重定向就是你买了这个店里的可乐 ,店里缺货,服务员只能告诉你让你去其他店里买,你又只好从头请求别的店。。
OK 对状态码200的字符表示
响应正文就是店里要打包的东西了, 服务员把麻婆豆腐.php打包成了响应正文
所以得到 {HTTP/1.1 200 OK 麻婆豆腐.php的实际内容lkashdgoahsdlkfa.....}


店员又做了我们刚刚打包的那些操作 一步一步向下层传递。  
到了邮递员手上, 骑着他的小电驴  不一会送到了我们家门前。
到此 我们的一次请求结束了! !!!
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页