您的位置:首页 > 运维架构 > 网站架构

从浏览器输入网址到显示网站页面之间到底发生了什么?系列(三)

2018-03-22 18:13 525 查看
    从上两篇文章我们已经简单知道了浏览器是如何发送请求消息和接收响应消息,以及浏览器如何使用UDP来向DNS服务器来查询域名的ip地址,那么这篇文章主要是讲OSI七层模型以及tcp/ip体系的五层模型,还有关于五层模型的在实际上具体操作。但是这篇文章我最后只会写到网络包通过网卡的PHY(MAU)转换成(光)电信号从网卡的RJ45端口发出为止,内容比较多并且专业,可能之前没有学过网络的同学会觉得有点复杂,但是这一章的内容绝对是重重点,想学好网络的必须熟悉,这里我不会写的十分的详细,因为要写详细的话,不知道要写多少篇才能讲清楚,我主要讲些重点的内容,有些同学说我写的文章思维有点乱,因为我写文章的经验不足,所以可能写的比较让人不容易明白,后面的文章我会尽量写的思维清晰一些。
   初步了解OSI七层模型(开放系统互连参考模型)以及TCP/IP体系的五层模型首先我们先简单了解下七层模型,顾名思义,它是有七层的,从底层到顶层分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。每层的作用大概是:   物理层:提供为建立、维护和拆除物理链路所需要的机械的、电气的、功能的和规程的特性;有关的物理链路上传输非结构的位流以及故障检测指示。
 数据链路层:在网络层实体间提供数据发送和接收的功能和过程;提供数据链路的流控。
 网络层:控制分组传送系统的操作、路由选择、拥护控制、网络互连等功能,它的作用是将具体的物理传送对高层透明。

 传输层:提供建立、维护和拆除传送连接的功能;选择网络层提供最合适的服务;在系统之间提供可靠的透明的数据传送,提供端到端的错误恢复和流量控制。

 会话层:提供两进程之间建立、维护和结束会话连接的功能;提供交互会话的管理功能,如三种数据流方向的控制,即一路交互、两路交替和两路同时会话模式 。

 表示层:代表应用进程协商数据表示;完成数据转换、格式化和文本压缩。

 应用层:提供OSI用户服务,例如事务处理程序、文件传送协议和网络管理等。
七层模型简单了解下就行,因为下面我们主要是按照TCP/IP五层模型来说。
TCP/IP五层模型:五层模型与七层模型的区别就是,没有了所谓的会话层和表示层,把它们的功能合并到了传输层,所以TCP/IP的五层模型体系从底层到顶层分别是:物理层,数据链路层,网络层,传输层,应用层,(有些材料书可能会说分为四层,但是我看了几本相关的书,我觉得还是分成五层来说比较清楚)其功能大概是:
物理层(physical layer):在物理层上所传数据的单位是比特。物理层的任务就是透明地传送比特流。
数据链路层(data link layer):常简称为链路层,我们知道,两个主机之间的数据传输,总是在一段一段的链路上传送的,也就是说,在两个相邻结点之间传送数据是直接传送的(点对点),这时就需要使用专门的链路层的协议。
网络层(network layer)主要包括以下两个任务:
(1) 负责为分组交换网上的不同主机提供通信服务。在发送数据时,网络层把运输层残生的报文段或用户数据报封装成分组或包进行传送。在TCP/IP体系中,由于网络层使用IP协议,因此分组也叫做IP数据报,或简称为数据报。
(2) 选中合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由器找到目的主机。
运输层(transport layer):负责向两个主机中进程之间的通信提供服务。由于一个主机可同时运行多个进程,因此运输层有复用和分用的功能。
应用层(application layer):是体系结构中的最高。直接为用户的应用进程提供服务。
知道了体系结构后,我们就可以根据层次来慢慢说明数据到底是如何发送的了。
但是我们还需要再简单了解下在协议栈中TCP/UDP两个的概念。

TCP(传输控制协议)

它是一种可靠,面向连接的传输协议,连接时使用三次握手,断开连接时使用四次挥手来保证连接,断连的可靠性,一般来说应用程序的收发数据,邮件等都是使用TCP来进行传输的,,而且它一定要保证对方收到了数据才肯罢休,是属于操作系统协议栈的一部分,

UDP(用户数据报协议)

 UDP是一种不需要连接,并且不可靠的协议,但是因为少了TCP那些繁琐的检测机制,使得他的速度会比TCP快些,它只会尽最大的能力交付,把东西直接扔给你就直接走人,不会管东西你到底有没有收到,一般来说,像音频,视频,或者数据较短这一类的东西,如果少了几个数据包不会影响太大(顶多卡顿一下),又需要速度的就可以使用UDP。他也是属于操作系统协议栈的东西,并且和TCP是同个阶层的。
像我们之前所说的DNS查询实际上用的就是UDP,
应用层给予了数据后,就会交给协议栈进行处理,协议栈主要是有TCP模块,UDP模块,IP模块组成。一般的浏览器使用的都是TCP协议进行数据的传输。但是有时候数据是很大的,就像我们的快递量很大,如果一次性载太多的话是容易翻车的。所以

数据的传输是有大小限制的

  应用程序发送给协议栈的数据大小一般是由应用程序本身来决定的,所以不同的应用会有不同的区别,有些程序会一次性把所有的数据都发送,有些程序则是逐字节或者逐行的传递数据,总之来说,一次将多少数据交给协议栈是由应用程序自行决定的,在这样的情况下,如果协议栈一收到数据就发出去,就可能会发送大量的小包,大大降低了网络的利用率,好比说一堆货物是逐个到达车库的,如果你一到一个货物就开车载走,可想而知这效率是多么的低,所以我们肯定会把数据积累到一定量的时候再进行发送,所以当应用数据到达了协议栈后,并不会马上会被发送刚出去,而是会被放在一个缓冲池里(就像一个仓库),但是要积累到多少才能发送了,主要是以下几个要素来进行判断
(一)MTU(最大传输单元)    它是一个网络包的最大长度,在以太网中就是以太包,大小一般是1500字节,而MSS是除去头部所能容纳的TCP数据的最大长度, 
  注:包的概念是头部加数据部分。不包括尾部,例如以太网包就不包括FCS.
(二)时间   当数据的传输效率不高的情况下,也就是货物到的比较慢,我们也不能等货物到达一定容量才进行发送吧,这样的话可能要等比较长的时间,所以时间这个因素也是很关键的,当到达某个时间时,如果货物还是没到达一定的容量,我们还是会选择发送 ,
实际上,这两个因素是相互矛盾的,如果长度优先的话,那么网络的效率就会提高,但可能会因为等待填满缓冲区的而产生延迟,相反的,如何时间优先,那么延迟时间就会变短,但是又会降低网络的效率。
TCP协议并没有告诉我们如何平衡,因此实际如何判断是由协议栈的开发者来决定的,由于这个原因,不同种类和版本的操作系统在相关的操作上存在着差异。
当协议栈收到数据后,会对数据进行拆分处理,类似我们的仓库收到货物后,就要对其进行一定规则的分类,例如按照重量进行分类,一辆车最多只能载20kg的货物,那么我们就按照这个重量来进行分批。所以我们

要对较大的数据进行拆分

  上面我们有说,当缓冲池的数据长度达到了MSS后,就不应该继续等待后面的数据了,此时就应该对其进行发送,但是一般来说,除了http消息这些比较小的数据,通常一个包就能搞定的的东西,我们是不需要对其进行拆分的,但是表单数据,文章数据,各种应用数据大多都是数据长度比较大的,我们就必须得对其进行拆分了,一般来说拆分的规则就是以MSS作为数据的最大长度来进行拆分,我们拿以太网举例,他的以太网包的MTU是1500字节,而一般的TCP首部和ip首部都是二十字节,所以剩下能放数据段的部分就只剩下了1460字节,(一般来说我们说的MTU是不包括MAC头部的),这样的话,假设我们应用层给了2000字节的数据吧,那么应该拆分成1460字节的一部分和540字节的一部分,然后每个部分加上一个20字节的TCP首部变成TCP报文段,也就是1480字节TCP报文段1和560字节报文段2,在TCP首部中有着各种寻路的信息,有个字段叫序号的,它的值是数据部分的首个字节号,例如报文段1的首部序号为1,报文段2的首部序号字段值为1461,而首部的ACK字段的值是表示下次想收到的的序号。例如报文段1收到后,服务器就会发送值为1461的ACK回去,表示下一个给我序号为1461的包啊,所以当服务器没有返回应该返回的ACK值时,那么我们可以确定它可能没有收到这个包,那么TCP就会进行补救(重传数据包),但是如果网络中断,服务器亢机等问题,TCP重传几次后发现还是没有用,就会向应用程序进行报错。

TCP的滑动窗口

如果像上面说的,每次发完一个包就要等待服务器发来正确的ACK,那么这种一来一回的方式就太花费时间了,在等待ACK号的这段时间里,我们应该继续发送后面的包,如果所示:



  当发送方的数据到达接收方后,在接收操作完成之后就需要向发送方返回ACK号,而再经过一段时间,当数据传递给应用程序之后才需要更新窗口大小,但如果根据这样的设计来实现,每收到一个包,就需要向发送方分别发送ACK号和窗口更新这两个单独的包,这样的话,包就太多了,因此接收方在发送ACK号和窗口更新时,并不会马上把包发送出去,而是会等待一段时间,在这个过程中很有可能会出现其他的通知操作,这样就可以把两种通知合并在一个包里发送的。举个例子,在等待发送ACK的时候正好需要窗口更新,这是就可以把ACK号和窗口更新放在一个包里发送,从而减少包的数量,但需要发送多个ACK时,因为ACK表示的是下一个想收到的序号,之前的都已经收到了,所以就可只发送最大的那个就好了,这样也能减少包的数量,当需要连续发送多个窗口更新时也是一样,因为连续发生窗口更新说明应用程序连续请求了数据,接收缓冲区的剩余空间连续的增加,情况和ACK的是一样的。只要发送最终的结果就行了。

IP包

 当应用数据被分块然后加上TCP首部称为TCP报文后,我们还需要将其交给协议栈的ip模块处理,主要的处理方式就是在前面多加个20字节的ip首部,这样刚好大小就是我们前面说的MTU了。我们对加了ip首部的数据包叫做ip包,ip首部主要是ip的控制信息,在ip模块中还会再加上一个mac头部,主要用于以太网规则,如果在ip包的前面加上了mac头部就变成了以太网包。

ip首部和mac首部

 两个首部都有着不同的作用,首先,发送方将包的目的地,也就是要访问的服务器的ip地址写入ip首部中,这样我们就知道这个包是要去哪里了,IP协议根据这个查找包应该传输的路线,然后,IP协议就会委托以太网协议将包传输过去,这时,IP协议会查找下一个路由器或者是主机的mac地址,并将这个mac地址写入mac首部中,这样的话,以太网协议就知道这个包是去哪的了
但是我们如何拿到Mac地址呢?

如何获取mac地址(通过ARP)

  mac首部是有14个字节的,共有三个字段,分别是接收方的mac地址,发送方的mac地址,和以太类型。我们都知道IP地址(ipv4)是有4个字节,而mac地址却是6个字节,也就是说有48个比特。所以以太类型字段占了是2个字节。发送方的地址很好写,其实就是计算机网卡的ROM里面的mac地址,这个地址网卡做的时候写入的,具有唯一性,这里有些人可能会误解为计算机的mac地址,实际上mac地址的个体是网卡,当一台计算机有多个网卡时,它也可以有多个mac地址,多个ip地址,而接收方的mac地址我们该如何确定呢?我们之前说过,域名被DNS解析成ip地址,所以这时候我们只有ip地址可以用,但是ARP可以利用ip地址查找到它的mac地址,实际上就是在同个子网里进行广播,请求ip地址为的xxx.xxx.xxx.xxx的主机的mac地址为多少,这时候每个人都收到,当有人发觉这个ip地址刚好跟自己的ip一致时,就会发出回应,这是我的ip地址,我的mac地址为xxx.xxx.xxx.xxx.xxx.xxx,(这个类似于在一个班里大喊,学号为1502222322的同学叫什么啊?然后就会有该学号的同学回应,是我,我叫张xx)

为加快速率的ARP的缓存机制

记得我在上篇文章有说过DNS是有缓存机制的,它会把查询到的信息记录起来,如果有需要就直接进行调用,ARP也是一样,例如想在计算机上查询ARP记录。可以在在命令行执行 arp -a



我们通过arp广播获取到了下一个路由器的mac地址后,就可以写入mac首部了,然后协议栈的功能也就大致完成了,
通过ip模块生成的包只是存放在内存中的一串数字信息,是没有方法直接发给对方的,我们需要将这些包来通过网卡进行转换发送。

将ip包转换成电(光)信号发送出去

我们先了解下网卡的结构 ,它主要是由缓冲池,ROM,mac模块,PHY(MAU)和RJ-45接口组成的。
缓冲池:用于临时保存要收发的内存空间
ROM:存放mac地址
Mac模块:控制碰撞检测,重发等以太网收发操作的部分。
PHY(MAU):发送和接收信号的电路。
RJ-45接口:连接网线的插座,如连接LAN网线,
网卡驱动从IP模块获取包之后,会将其复制到网卡的缓冲池中,然后向MAC模块发送包的命令。然后MAC模块会将包从缓冲区中取出,并在以太网包的前面加上报头和起始帧分界符,在尾部添加FCS.
然后PHY模块会将信号转化成可在网线上传输的格式通过RJ-45接口的网线传输出去。然后计算机的数据发送也就大致完成了。
下一篇文章讲集线器,交换机,路由器的数据传输。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: