网络是如何链接的?网络发展简介(四)

从浏览器地址栏输入后敲下回车,直到浏览器呈现信息,这个过程到底发生了什么?前端

这一过程涉及宽带接入、浏览器、前端技术,DNS,TCP/IP,操做系统,网卡,驱动程序,传输设备,交换机、路由器,服务器等等网络、通讯、web相关的几乎全部技术
本文只是宏观上简单的了解,加深本身对网络链接的理解,不是大而全的技术论文
只是一个过程了解,阅读须要对网络、web有所了解
 
在前文中,我有上面两幅图, 网络的通讯相似快递的运输
计算机网络传输的核心是TCP/IP协议,分为四层结构
应用层产生须要传输的真正数据。
传输层、网际层、网络接口层由操做系统以及网卡驱动程序和物理网卡实现,负责将数据从计算机中发送出去,通过路由器(网际层)等网络设置到达最终的目的地。
本文以发送HTTP请求以及返回响应的过程简单介绍网络的通讯

浏览器发起请求

解析URL

打开浏览器以后,能够在地址栏输入网址(或者点击某个超连接)本质是同样的,网址就是URL
URL是Uniform Resource Locator的缩写,译为“统一资源定位符”,一般由三部分组成,协议,ip地址(或者域名)以及资源的具体目录(第三个也能够省略)
https是协议 ,www.cnblogs.com是域名,noteless是资源具体路径
输入网址,按下回车后,浏览器的目的就是请求这一“URL”的资源,并将解析呈现出来。
浏览器首先要解析URL,进一步肯定通讯协议
应用层不止一种协议,有http、ftp、file、https 等,每种协议天然有不一样的约定方式
因此须要先肯定协议,协议是什么?协议就是相互之间的一个约定,好比我给你一块钱,你给我一瓶矿泉水,这就是约定,约定好了你们就按照协议进行执行。
解析URL以后,浏览器解析出URL给出的信息

HTTP请求

咱们输入的网址是https协议,简单起见以HTTP来了解
HTTP 协议定义了客户端和服务器之间交互的消息内容和步骤,你们按照固定的步骤和格式进行通讯
根据URL能够定位请求资源的位置,可是对于这个资源可能还有多种处理方法,好比是请求资源仍是要删除指定资源?
因此HTTP请求也规定了方法,用于指定请求的类型
HTTP主要请求方法为 GET  POST
 
如上图所示,HTTP主要有两类报文,一个是从客户端向服务器发送请求,一个是服务器到客户端的应答
下面就是请求和响应的格式
请求和响应都由三部分组成,首行、头部以及实体
请求报文 中分别叫作, 请求行,请求头,请求体
响应报文 分别叫作: 状态行(响应行),响应头,响应体
每一部分又都由多个字段约定了更加详细具体的通讯规则
在浏览器中能够查看到这些信息,好比chrome中查看https://www.cnblogs.com/noteless/ 的请求和响应信息
在查看工具中看的信息,为了更加直观,工具对原始数据进行了必定处理,因此不是上面的HTTP格式,不要奇怪
 
总之
浏览器将须要请求的信息,按照HTTP协议约定的格式,封装成为HTTP请求报文

DNS解析

HTTP请求是应用层协议,自己不具有将消息发送到网络的功能
想要进一步进行通讯,还须要调用操做系统提供的socket接口,与服务器创建链接进行通讯
socket是操做系统对TCP/IP的封装,提供应用编程接口,想要依赖socket进行通信,须要ip地址和端口号
此时,咱们仅仅知道服务器的名称,也就是域名www.cnblogs.com
须要获取到服务器的真实IP地址,才可以真正的进行通讯
解析的过程:
操做系统会 先检查本身本地的hosts文件 ,若是hosts里没有这个域名的映射,则查找本地DNS解析器缓存
若是hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的 首选DNS服务器 ,叫作本地DNS服务器
本地DNS解析器是操做系统中的DNS客户端程序,负责DNS的解析管理
因此,以上的步骤就是
hosts文件有没有?
操做系统的客户端--本地DNS解析器缓存  有没有?
尚未?去配置的DNS服务器中进行查找!
 
若是要查询的域名,不禁本地DNS服务器区域解析
但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具备权威性
 
若是本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发)进行查询
若是未用转发模式,那么迭代查询
本地DNS就把请求发至 “根DNS服务器”,“根DNS服务器”收到请求后会判断这个域名(.com)是谁来受权管理,并会返回一个负责该顶级域名服务器的一个IP。
本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。
这台负责.com域的服务器收到请求后,若是本身没法解析,它就会找一个管理.com域的下一级DNS服务器地址(cnblogs.com)给本地DNS服务器。
当本地DNS服务器收到这个地址后,就会找cnblogs.com域服务器,重复上面的动做,进行查询,直至找到www.cnblogs.com主机。
 
若是用的是转发模式,那么递归查询
此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析
上一级服务器若是不能解析,或找根DNS或把转请求转至上上级,以此循环。
 
无论本地DNS服务器是否使用转发,最后都是把结果返回给本地DNS服务器,而后由此DNS服务器再返回给客户机。
 
本地DNS服务器解析的过程,就是前面提到的DNS的查询
主机到本地域名服务器的查询是递归查询
本地域名服务器的查询过程,能够是递归查询,也能够是迭代查询
 
DNS解析以后就得到了请求域名的IP地址,对于HTTP请求,若是没有设置那么默认是80端口
若是设置的话,那么就是使用指定的端口
端口号会设置在URL中,浏览器客户端解析URL就能够得到,不须要专门的解析
因此此时,拥有了Ip地址和端口号

socket链接

socket是操做系统提供的TCP/IP的薄层封装,大大简化了TCP/IP的使用
借助于socket通讯的过程大体分为下面四个过程
  1. 建立套接字
  2. 链接阶段
  3. 通讯阶段
  4. 断开阶段
web服务器会先建立套接字,而后进行监听,等待客户端进行链接
下图是一个简化版,简化版,简化版,socket链接请求的过程
 
socket是对TCP/IP协议的封装,因此本质仍是TCP/IP,接下来的TCP/IP中会继续介绍

TCP处理

tcp报文格式、字段

若是应用层的数据过大,会将数据进行分块,每一个块都会添加TCP头部信息
以下图所示
 
 
TCP协议与HTTP协议同样,协议就是一种约定好的格式
TCP的头部的全部字段信息,体现了TCP协议全部的功能,TCP协议模块的实现就是对这些字段的解析使用处理
 
源端口和目的端口
各占2个字节,分别写入源端口号和目的端口号。
序号
序号占4字节
序号范围是[0, 232 - 1 ],共232(即4 294 967 296)个序号。序号增长到232-1后,下一个序号就又回到0。
也就是说,序号使用mod 232运算。
TCP是面向字节流的。在一个TCP链接中传送的字节流中的每个字节都按顺序编号。
确认号 
确认号 占4字节
是指望收到对方下一个报文段的第一个数据字节的序号
若确认号=N,则代表:到序号N-1为止的全部数据都已正确收到
确认ACK
仅当ACK=1时确认号字段才有效。当ACK=0时,确认号无效
TCP规定,在链接创建后全部传送的报文段都必须把ACK置1
 
同步SYN
在链接创建时用来同步序号
当SYN=1而ACK=0时,代表这是一个链接请求报文段。
对方若赞成创建链接,则应在响应的报文段中使SYN=1和ACK = 1
所以,SYN置为1就表示这是一个链接请求或链接接受报文。
终止FIN
用来释放一个链接
当FIN = I时,代表此报文段的发送方的数据己发送完毕,并要求释放运输链接

TCP三次握手

TCP运输链接有三个阶段:链接创建、数据传送、链接释放
TCP链接过程一般叫作 握手 ,握手须要客户端和服务器端交换三个报文,以下图所示
之因此须要三次握手是由于TCP是可靠传输,三次可以恰好可靠又很少余
TCP三次握手与Socket的链接过程是相关联对应的,Socket就是对于TCP/IP的封装么
客户端有CLOSED、SYN-SEND、ESTABLISHED三种状态
客户端有CLOSED、LISTEN、SYN-RCVD、ESTABLISHED四种状态
服务器会首先建立链接,而且进入监听等待阶段,等待客户端的请求
当须要发送请求时,浏览器客户端主动打开链接,而后服务器被动打开链接
 

链接过程

客户端在须要时,向服务器发起请求链接报文,发出后状态从CLOSED转换为SYN-SEND  同步-已发送状态
服务器一直处于LISTEN状态,接收到请求后,对客户端的请求进行回应,转换为SYN-RCVD,同步-已收到状态
客户端收到服务器的回应后,状态转换为ESTABLISHED,而且再次向服务器发送确认
服务器收到客户端的确认以后,服务器也转换为ESTABLISHED状态,完成了链接
发出消息或者收到消息后状态才会进行切换
客户端与服务器的握手是一个往复确认的过程
客户端:发出确认请求,SYN=1,seq=x,你听获得么,我想创建链接(SYN=1),个人序号是x(seq=x)
服务器:对请求进行确认,也就是回应,我听到了(ACK=1,ack=x+1),你听获得么(SYN=1),个人序号是y(seq=y)
客户端:对服务器的回应进行确认,我听到了(ACK=1,ack=y+1),个人序号是x+1
 
IP数据报通过运输层须要分段发送,因此在TCP的处理过程当中,有序号的概念
好比客户端说我要从666号开始,发送100个数据,服务器说,我是从888号开始回应的
上面的seq=x  和 seq=y   seq=x+1(上一个seq=x,下一个天然就是seq=x+1了)都是各自的序号
 
握手的过程就是SYN seq   ACK ack的来回确认 
SYN  ACK是头部的字段,能够理解为标志位,协议中有对他们的值有具体的规定
ack就是确认号,确认号是指望收到的对方的下一个报文段的第一个数据字节的序号,也就是收到的序号+1
不然随便一个,怎么对得上号

为何要三次握手?

若是不是三次握手,只有两次
若是客户端发出请求链接时,报文延时了,因而客户端从新发送了一次链接请求消息
后来收到了确认,创建了链接,而后完成了数据传输,关闭了链接
此时,服务器收到了那个迟到的请求消息,此时他应该是个废物了
可是若是只有两次握手,服务器收到请求就响应创建了链接了
可是若是是三次,客户端不会再次确认,服务器也就随后知道了这消息有问题,不会创建链接

TCP四次挥手

链接创建之后就能够进行数据通讯传输了
通讯结束后,须要断开链接,断开链接须要四次交互,常被称为 四次挥手
最初状态均为ESTABLISHED ,客户端与服务器相互进行数据传送
下图假设客户端无数据发送,请求断开链接

断开过程

客户端无数据发送时,请求关闭链接,我好了,我想断开链接了(FIN=1)个人序号是u(u就是以前传送过的全部数据的最后一个字节的序号+1)
此时客户端转变为FIN-WAIT-1状态
服务器收到客户端的消息后,告诉客户端“好的,我知道了”(ACK=1,ack=u+1),这条消息的序号是v(seq=v ,这是服务器发送消息的序号)
此时服务器的状态就转换为了CLOSE-WAIT状态
 
此时,客户端通往服务器的路就断开了,客户端不能向服务器发送数据
可是服务器仍旧能够向客户端发送数据,如今是“半关闭”的状态
 
当客户端收到来自服务器的确认以后,进入FIN-WAIT-2状态,等待服务器那边说断开链接,等待中。。。。。
 
当服务器全部的数据也都彻底发送完成了以后,服务器才开始主动告知客户端断开链接(FIN=1,seq=w)
这中间服务器可能又继续发送了一些数据,多是v+1 也可能发送了更多,因此设置为w
而且再次发送确认信息(ACK=1,ack=u+1,由于客户端已经不能发送数据了,服务器指望收到的序号永远都是最后一个序号+1,也就是u+1)
这时,服务器就进入了LAST-ACK状态,最后确认状态
 
客户端收到了服务器的断开链接请求后,也须要给出确认响应(ACK=1,ack=w+1,seq=u+1),而后进入TIME-WAIT状态
等待两个MSL后,进入关闭状态
MSL 是Maximum Segment Lifetime英文的缩写“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
 
服务器最终收到来自客户端的确认信息后,关闭,进入CLOSED状态
 
四次挥手也是一个互相确认的过程,你说不玩了,别人答应了,还要等别人都搞好了再告诉你能够走了,你才能走
客户端:我不想玩了
服务器:好的我知道了
服务器:你能够走了
客户端:好的我走了
 
就如同在网吧上网,你点击下机以后,再去网管那边结帐
结帐清楚了以后才完全结束,而不是你说走就走了,难道你办会员卡了么
 
这个过程很好理解, 客户端发出请求后,并不意味着服务器都已经完成响应
因此当客户端请求断开时,并不能当即断开,还须要等待服务器那边处理稳当,再来通知你的确是能够断开了
消息发出来谁知作别人收没收到,因此还须要一个确认
 

为何还须要等待2MSL?

为了保证客户端发送的最后一个确认,可以达到服务器
这个ACK可能丢失,就会致使服务器在LAST-ACK状态,没办法正常结束,那么服务器收不到就会超时重传能够断开的消息
那么A就可以在这个2MSL中收到这个重传的消息,而且从新计时2MSL
 
并且,客户端持续2MSL时间后断开,就能够保证这个链接的全部报文都会死亡,能够看下MSL的含义,也就是2MSL以后,断开这个链接以后,确定不会还存在这个链接的旧的报文了
上面说的过程虽说得是TCP的交流,可是尽管同层之间看似同层交换,可是能不用底层的协议嘛,TCP的数据也还都是要通过IP层,链路层、网卡、路由,同样不缺

IP层处理

TCP 模块在执行链接、收发、断开等各阶段操做时,都须要委托 IP 模块将数据封装成包发送给通讯对象。

关于TCP和IP的分段

咱们以前讲过TCP会进行分段,IP也会进行分段,看起来有点奇怪
有两个概念:
MTU (Maximum Transmission Unit,MTU), 最大传输单元 ,以太网和802.3对数据帧的长度都有一个限制,其最大值分别是1500和1492个字节
MSS (Maxitum Segment Size) 最大分段大小 ,TCP数据包每次可以传输的最大数据分段,每每MSS为1460
因此说TCP分段的缘由是MSS,IP分片的缘由是MTU
对于TCP来讲,MSS<MTU,因此说, 对于TCP报文,IP不须要再继续对他进行分段了
可是IP是为运输层服务的,不只仅是为了TCP,还有UDP,UDP则极可能会致使IP分段
首部由两部分组成,分为固定部分和可变部分(就是固定参数和可选参数的概念)
这些数据都是由操做系统组装生成的,好比目的地址就是来源于应用程序的层层传递
 

ip地址与硬件地址

ip地址是网际层以及以上使用的,是一种逻辑地址,不存在物理实体,由于IP地址是用软件实现的 ,没有一台机器被写死某个IP
数据通过IP处理封装后,数据报会交给数据链路层,会被封装成MAC帧
MAC帧在传送时,使用的是物理地址,源地址和目的地址都是硬件地址,这两个地址被写入MAC帧的头部
链接在通讯线路上的网络设备(主机或者路由器)在收到MAC帧以后,根据MAC帧首部的硬件地址决定收下或者丢弃。
总之,IP地址保存在IP数据报的首部,MAC地址保存在MAC数据报的首部
网际层以及网际层以上使用IP地址,数据链路层以及如下使用硬件地址
硬件地址就是网卡的地址,任何一块网卡,都有一个惟一的物理地址,这就是MAC地址,因此叫作硬件地址,由于是被写死固化在网卡中的
一个网卡就有一个MAC地址,若是计算机中安装多个网卡,那么就会有多个MAC地址
 
既然有了IP为何还要使用MAC?或者说有了MAC为何还须要IP呢?
IP层关注的是网际层的传输,可是具体的数据传输必然没法脱离具体的物理线路以及组网环境
IP地址是根据网络的拓扑结构分配的,因此根据IP能够实现高效的路由选择
物理地址跟网络拓扑结构没有任何关系,显然不适合用来路由选择,并且,若是物理地址跟网络拓扑创建了关联
那么,对于设备的更换,或者网卡的更换,将会增长难度
并且,实际的物理组网环境多变复杂,因此才会分为网际层和网络接口层,因此才会同时使用IP地址和MAC地址
IP地址能够实现高效的路由选择,MAC地址实现相邻链路间的数据传送
应用层经过借助于操做系统的DNS解析能够得到接收方的IP地址,操做系统也知道本机的IP地址
那么如何肯定目的MAC?
答案是 经过路由表这是操做系统实现的功能,其实也仍是借助于各类协议来生成的,说白了就是计算规则,先找到下一个中转设备的IP地址
而后再借助于ARP协议 ,查询MAC地址
 
在windows下能够经过命令 route print查看

路由表是怎么来的?

有几种常见的路由选择协议,路由选择协议的核心就是路由选择算法
互联网采用分层次的路由选择协议
由于互联网的规模自己很是大,不可能让全部的路由都知道全部的网络怎么到达,这是不现实的
另外自己不少单位,并不但愿外界了解本身内部的路由选择协议以及网络布局细节
因此互联网被划分为了多个 自治系统(autonomous system AS)
其实仍是分片管理,区域自治的思想
在目前的互联网中,一个ISP就是一个自治系统,这样互联网的路由选择协议就分为两大类
一个是AS内部,一个是AS与AS之间
内部网关协议IGP   Interior Gateway Protocol,AS内部使用的路由选择协议,目前主要是RIP和OSPF
外部网关协议EGP  External Gateway Protocol,两个AS之间相互联系时使用的协议,目前是BGP-4(版本4)
自治系统之间的又叫作 域间路由选择 ,自治系统内部的路由选择叫作 域内路由选择
路由选择协议是一个自学习的过程,经过相互之间的信息互换最终造成了路由表
想要了解具体的学习过程能够查看路由选择协议的相关资料
路由表怎么使用?
 
网络目标(destination)  目的地网段
网络掩码(mask)子网掩码
网关(gateway)下一跳路由器入口的ip
若是是本地计算机直接链接到的网络,网关一般是本地计算机对应的网络接口,可是此时接口必须和网关一致;
若是是远程网络或默认路由,网关一般是本地计算机所链接到的网络上的某个服务器或路由器
接口(interface)  接口定义了针对特定的网络目的地址,本地计算机用于发送数据包的网络接口
跃点数(metric)  可理解为跳数表示该条路由记录的质量通常状况下,若是有多条到达相同目的地的路由记录路由器会采用metric值小的那条路由
 
简单说就是在“网络目标“里面查找匹配,匹配到了就使用”接口“ 发往”网关“。
网络目标0.0.0.0  表示默认路由,也叫作缺省路由,若是路由表匹配不到则经过这一条记录执行
127.0.0.0  表示环回地址,系统将接收发送给该网段的全部数据包
 
总之,经过这个路由表
咱们就可以获得想要发送到目的地IP,下一跳的IP地址是什么,以及网络接口的IP地址,也就是发送方的IP地址

下一跳的IP地址有什么用?

有了下一跳IP地址,咱们就能够查找他的物理地址,这样就能够得到下一个设备的MAC地址了
如何根据IP地址查询MAC地址呢?
答案是经过ARP协议
ARP 地址解析协议Address Resolution Protocol
网络层使用的是IP地址,但在实际网络的链路上传送数据帧时,最终仍是必须使用该网络的硬件地址。
但IP地址和下面的网络的硬件地址之间因为格式不一样而不存在简单的映射关系 (例如,IP地址有32位,而局域网的硬件地址是48位),也就是说没办法单纯的像个文件同样一一对应,或者写死的那种
此外,在一个网络上可能常常会有新的主机加入进来,或撤走一些主机
更换网络适配器也会使主机的硬件地址改变
地址解析协议ARP解决这个问题的方法是:
在主机ARP高速缓存中存放一个从IP地址到硬件地址的映射表,而且这个映射表还常常动态更新(新增或超时删除)。
每一台主机都设有一个ARP高速缓存(ARP cache),里面有本局域网上的各主机和路由器的IP地址到硬件地址的映射表
假设须要查找主机B,IP地址为X,B可能新来的,也可能主机才开始运行,缓存为空,总之,没有差找不到IP地址为X的主机B的信息
首先 ,ARP在局域网上 广播发送ARP请求分组
大体内容是:“个人IP地址是XXX,个人MAC地址是YYY,我想找IP地址为ZZZ的主机收到请回答
而后 局域网内全部运行ARP的主机都会收到这个请求
最后 主机B的IP地址就是请求中要查询的主机,因此会应答,其余人则不理睬这个请求,由于不是找他们的
ARP请求是广播,这个响应就是普通的单播了
此时一旦收到了响应就获得主机B IP地址为X的物理地址了
 
因为是IP协议使用了ARP协议,所以一般就把ARP协议划归网际层
但ARP协议的用途是为了从网络层使用的IP地址,解析出在数据链路层使用的硬件地址。因此有的书又说是链路层
此时通过路由表和ARP协议咱们得到了目的MAC地址
 
IP 生成的网络包只是存放在内存中的一串数字信息,没有办法直接发送给对方
接下来就是数据链路层的相关职责,数据链路层属于计算机网络的低层
数据链路层使用的信道主要有如下两种类型:
点对点信道 这种信道使用一对一的点对点通讯方式。使用的协议有ppp点对点协议
广播信道 这种信道使用一对多的广播通讯方式,所以过程比较复杂
广播信道上链接的主机不少,所以必须使用专用的共享信道协议来协调这些主机的数据发送。
广播信道能够进行一对多的通讯,局域网使用的就是广播信道
以太网(Ethernet)是一种计算机局域网技术规范,以太网是目前应用最广泛的局域网技术,他可不是某种具体的网络
 
因此接下来就是借助链路层处理封装成帧进行传输了
 

链路层处理

计算机与外界局域网的链接是经过通讯适配器(adapter)进行的,也就是网卡
网卡上装有RAM和ROM
适配器和局域网之间的通讯是经过电缆或者双绞线串行传输方式通讯
适配器和操做系统之间的通讯是经过主板上的IO总线并行传输的
网卡的正确运行还须要操做系统安装 网卡驱动程序
他们掌管着应当从存储器的什么位置上把多长的数据块发送到局域网
或者应当在存储器的什么位置上把局域网传送过来的数据块存储下来
还要可以实现以太网协议
 
适配器在接收和发送各类帧时,不使用计算机的CPU,这时计算机中的CPU能够处理其余任务。
当适配器 收到有差错的帧时,就把这个帧直接丢弃 而没必要通知计算机。
当适配器 收到正确的帧时,它就使用中断来通知该计算机 ,并交付协议栈中的网络层。
当计算机要发送IP数据报时,就由协议栈把IP数据报向下交给适配器,组装成帧后发送到局域网。
网卡驱动程序部分就是实现链路层的相关协议的实体
 
数据链路层协议有许多种,但有三个基本问题则是共同的。
这三个基本问题是: 封装成帧、透明传输和差错检测
封装成帧
封装成帧((framing)就是在一段数据的先后分别添加首部和尾部,这样就构成了一个帧。
接收端在收到物理层上交的比特流后,就能根据首部和尾部的标记,从收到的比特流中识别帧的开始和结束。
透明传输
“透明” 它表示:某一个实际存在的事物看起来却好像不存在同样
“在数据链路层透明传送数据”表示不管什么样的比特组合的数据,都可以按照原样没有差错地经过这个数据链路层
所以,对所传送的数据来讲,这些数据就“看不见”数据链路层有什么妨碍数据传输的东西。或者说,数据链路层对这些数据来讲是透明的。
使用专门的控制字符,若是出现控制字符则插入转义字符,这种方法被称为 字节填充
差错检测
现实的通讯链路都不会是理想的,这就是说,比特在传输过程当中可能会产生差错
1可能会变成0,而0也可能变成1。这就叫作比特差错。比特差错是传输差错中的一种  
目前在数据链路层普遍使用了循环冗余检验CRC (Cyclic Redundancy Check)的检错技术。
 
经常使用的以太网MAC帧格式有两种标准,一种是DIX Ethernet V2标准(即以太网V2标准),另外一种是IEEE的802.3标准。
 
 
 
就这样,通过驱动程序和网卡,数据就被从TCP层再到IP层再到链路层再到物理层完成了数据从计算机端口的输出
 
注意,以上TCP、IP、链路层的处理,都是由操做系统以及网卡驱动程序按照TCP/IP的协议以及以太网等相关技术实现的
上面各个模块功能的划分描述只是大体的通常性的
操做系统到底实现到协议的哪一部分以及网卡驱动到底实现到哪一部分的细节,彻底由实现决定

数据转发接收

数据从应用层,通过操做系统和网卡驱动程序对协议栈的实现,在通过网卡转换为广电信号从网口发送出去
接下来就是借助于网络设备进行数据传送
设备主要是交换机、路由器。不过如今路由器都集成了这几个的功能
可是本质是同样的,能够理解为网络设备传输须要某些功能,而这几种功能经过交换机、路由器实现了
随着技术发展,设备的功能集成度很高,家用路由器都集成了这些功能
也有三层交换机,实现了转发和路由的功能
因此,根本是咱们要理解交换机、路由器这几个设备的功能点,从而了解数据处理过程,究竟是个什么设备咱们能够不用关心
先了解下发展,最初的设备是 集线器
集线器的英文称为“Hub”。“Hub”是“中心”的意思, 集线器的主要功能是对接收到的信号进行再生整形放大,以扩大网络的传输距离
集线器属于物理层设备 ,与网卡、网线等传输介质同样,属于局域网中的基础设备, 集线器(hub)属于纯硬件网络底层设备
因为集线器会把收到的任何数字信号,通过再生或放大,收到1就转发1,收到0就转发0
从集线器的全部端口提交,这会形成信号之间碰撞的机会很大
并且 集线器不进行碰撞检测,若两个接口同时有信号输入(即发生碰撞),那么全部的接口都将收不到正确的帧
并且 信号也可能被窃听 ,而且这表明全部连到集线器的设备,都是属于同一个碰撞域名以及广播域名,所以大部份集线器已被交换机取代。
组建局域网能够用集线器,也能够用交换机。经过集线器链接的一组工做站同属一个冲突域,也同属一个广播域
 
为了可以具备更高性能的扩展以太网,出现了 网桥 网桥对收到的帧根据其MAC帧的目的地址进行转发和过滤。
网桥收到一个帧时,并非向全部的接口转发此帧
而是根据此帧的目的MAC地址,查找网桥中的地址表,而后肯定将该帧转发到哪个接口,或者是把它丢弃(即过滤)
 
再后来又出现了 交换机 (二层交换机),核心与网桥差很少,可是改进了不少,反正 交换机是网桥的进化版本就是了
交换机也被称为 多接口的网桥
以太网的交换机的每一个接口都直接与一台主机或者另外一个以太网交换机链接,而且是 全双工模式
全双工就比如双向两车道(两个方向能够同时进行),若是其中一条道堵上了,被堵方向的车辆就须要借道,双方交替,某一瞬间只能有一辆车经过,这就是半双工。
并且,以太网还具备并行性,即同时联通多接口,使多对主机同时进行通讯(网桥只能一次分析和转发一个帧)相互通讯的主机都是独占传输媒体,无碰撞的进行数据传输。
交换机根据MAC地址转发是借助于内部的交换表,是经过自学习算法自动的创建起来的
交换机使用专用的交换芯片,用硬件转发,其转发效率比用软件转发的网桥快不少

交换表是如何学习的?

假设最开始是空的,当A发送数据给B时,从1进入,交换机将A,1 记录在表中
此时交换机不知道要送到哪里,因此广播(转发到除了入口以外的全部端口),C,D会丢弃,B会接收到
B要发送给A时,从3进入,交换机将B,3记录在表中,查表获得A的端口1,因此从1转发出去
只要通过这样的步骤,只要C,D也发送数据,那么就最终会将全部主机的地址与端口进行匹配,就获得了完整的交换表
 
表中的 数据都是有时效性的 ,过时的条目会被自动删除,因此能够很方便的更换主机,哪怕主机更换网卡
 
不过这个自学习的过程,某种条件下会产生问题,可能会成环
假如,最开始A经过1 向B发送一帧,交换机1#广播,假设3收到后发送到交换机2#的1号口,而后再到2号口,造成了环装,浪费了资源
为了解决这种问题,有一个协议 生成树协议STP Spanning Tree Protocol,主要就是为了 不改变网络拓扑结构的状况下,切段环形
 
若是交换机收到的目的地址就是源端口地址,会简单的丢弃包
由于A发出后,通过集线器会发送给B,若是交换机再将这个包返回,达到集线器以后,会再次的发送给A和B,这是有问题的
此外,若是接收方MAC地址是一个广播地址 A,那么交换机会将包发送到除源端口以外的全部端口。
 
网桥和交换机用于分割冲突域
冲突域简单理解就是链接在一块的节点的集合,集线器链接的全部节点,就是一个冲突域,由于他不作任何区分,全部的数据都广播发到全部节点
网桥和交换机工做在链路层,会根据MAC地址进行转发,因此能够分割冲突域 ,减小了没必要要的广播数据,让网络通道舒服了一些
 
路由器是一种具备多个输入端口和多个输出端口的专用计算机,其任务是转发分组
从路由器某个输入端口收到的分组,按照分组要去的目的地(即目的网络),把该分组从路由器的某个合适的输出端口转发给下一跳路由器
下一跳路由器也按照这种方法处理分组,直到该分组到达终点为止。路由器的转发分组正是网络层的主要工做

路由器的结构

路由器包括 转发模块 端口模块 两部分
路由器的行为和交换机是相似的,只不过路由器工做在网络层,处理的是IP
路由器的端口的硬件将包接收进来
接下来,转发模块会根据接收到的包的 IP 头部中记录的接收方 IP 地址,在路由表中进行查询,以此判断转发目标。
而后,转发模块将包转移到转发目标对应的端口,端口再按照硬件的规则将包发送出去
路由器的端口具备MAC 地址,因此他能够做为以太网的接收方和发送方,端口还具备 IP 地址
首先路由器端口会接收发给本身的以太网包,而后查询转发目标,再由相应的端口做为发送方将以太网包发送出去
这一点和交换机是不一样的,交换机只是将进来的包转发出去而已,它本身并不会成为发送方或者接收方
须要记住:路由器的各个端口都具备 MAC地址和 IP 地址
交换机在地址表中只匹配彻底一致的记录,而路由器则会忽略主机号部分,只匹配网络号部分
这涉及到子网划分,总之路由器只看网络号,不关注具体的门牌号,负责到小区,这也是路由表中为什么有子网掩码的信息,由于路由器须要知道网络号的位数
路由器中的路由表和上面计算机操做系统中的路由表是一个概念 ,逻辑思路也是同样的
只不过具体实现确定不一样(操做系统的代码跟路由器的代码怎么可能同样)
 
对路由表进行维护的方法有几种,大致上可分为如下两类。
  1. 由人手动维护路由记录
  2. 根据路由协议机制,经过路由器之间的信息交换由路由器自行维护路由表的记录
其中 2 中提到的路由协议有不少种,例如RIP、OSPC、BGP 等都属于路由协议
 
路由表记录维护的方式和交换机也有所不一样
交换机中对 MAC 地址表的维护是包转发操做中的一个步骤
而路由器中对路由表的维护是与包转发操做相互独立的,也就是说,在转发包的过程当中不须要对路由表的内容进行维护。
前面讲到的交换机会在转发时记录端口与mac,路由器进行分租转发过程当中不会作相似的事情

路由器处理过程

再次梳理下路由器的处理过程:
首先信号到达网线接口部分,而后经过网卡将信号转换为数字信息
而后经过包末尾的 FCS 进行 错误校验 ,若是没问题则 检查 MAC 头部 中的接收方 MAC 地址
确认是否发给本身的包,若是是就放到接收缓冲区中,不然就丢弃这个包。 
路由器的端口都具备MAC地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃。
计算机网卡对数据的接收也是这样子的,网卡和驱动程序负责了这部份内容
 
而后,完成包接收操做以后,路由器就会丢弃包开头的 MAC 头部。
由于MAC 头部的做用就是将包送达路由器,完成这一段链路上数据的传送,若是这个下一站是路由器,那么其中的接收方 MAC 地址就是路由器端口的 MAC 地址。
所以,当包到达路由器以后,MAC 头部的任务就完成了,因而 MAC头部就会被丢弃。
 
接下来路由器会根据 IP 头部中的内容进行包的转发操做
转发操做分为几个阶段,首先是查询路由表判断转发目标
路由器根据路由表进行匹配的时候, 路由器首先寻找网络号比特数最长的一条记录
由于网络号比特数越长,说明主机号比特数越短,也就意味着该子网内可分配的主机数量越少,即子网中可能存在的主机数量越少
这一 规则的目的是尽可能缩小范围 ,因此根据这条记录判断的转发目标就会更加准确
 
若是路由器发送出现问题,路由器会丢弃这个包,并经过ICMP 消息告知发送方主机。
这里的处理方式和交换机不一样, 缘由在于网络规模的大小。
交换机链接的网络最多也就是几千台设备的规模,遇到不知道应该转发到哪里的包
交换机能够将包发送到全部的端口上,虽然这个方法很简单粗暴,但不会引起什么大问题。
但是,路由器工做的网络环境就是互联网,它的规模是远远大于以太网的,因此不能将包发送到整个网络上,那就会产生大量的网络包,形成网络拥塞。
所以,路由器遇到不知道该转发到哪里的包,就会直接丢弃。
ICMP
为了更有效地转发IP数据报和提升交付成功的机会,在网际层使用了 网际控制报文协议ICMP (Internet Control Message Protocol)
ICMP容许主机或路由器报告差错状况和提供有关异常状况的报告。
ICMP是互联网的标准协议。
但ICMP不是高层协议(看起来好像是高层协议,由于ICMP报文是装在IP数据报中,做为其中的数据部分),而是IP层的协议。
ICMP报文做为IP层数据报的数据,加上数据报的首部,组成IP数据报发送出去。

下一步的前置处理

路由器的转发与计算机操做系统中IP实现模块的工做核心点是同样的,他们都是负责交付IP数据报
路由器从路由表中查询到转发目标以后,数据包会转发给指定的端口
在此以前还须要作一系列的处理
TTL
第一个工做是更新 IP 头部中的 TTL(Time to Live,生存时间)字段
TTL 字段表示包的有效期,包每通过一个路由器的转发,这个值就会减 1,当这个值变成 0 时,就表示超过了有效期,这个包就会被丢弃,防止死循环永远发送。
分片
路由器的端口并不仅有以太网一种,也能够支持其余局域网或专线通讯技术。
不一样的线路和局域网类型各自能传输的最大包长度也不一样,所以输出端口的最大包长度可能会小于输入端口。
即使两个端口的最大包长度相同,也可能会由于添加了一些头部数据而致使包的实际长度发生变化,ADSL、FTTH 等宽带接入技术中使用的 PPPoEB 协议就属于这种状况。
不管哪一种状况,一旦转发的包长度超过了输出端口能传输的最大长度,就没法直接发送这个包了。
遇到这种状况,可使用 IP 协议中定义的分片功能对包进行拆分,缩短每一个包的长度。
查询物理地址
与计算机操做系统的处理相似,知道了目标地址,能够根据ARP协议查询目的MAC
路由器的端口也具备网卡,具备MAC以及IP,因此就是网卡负责链路层帧的封装以及光电信号的转换,而后发送
就是这样一段一段,就像快递同样,就到达了最终的目的地
 
IP(路由器)负责将包发送给通讯对象这一总体过程,而其中将包传输到下一个路由器的过程则是由以太网(交换机)来负责的。
整个传输过程当中,目的IP并不会发生变化
虽然咱们经过路由表查找下一跳的IP地址,可是是为了查询下一个设备的物理地址,进而借助于以太网进行发送
下一跳的IP地址并不存在与传输线路上,传输线路上一直都是目的IP,而以太网的源MAC和目的MAC倒是一直在变化的
因此说,IP负责包发送给通讯对象这一总体过程,以太网交换机负责将包传输到下一个路由器。
为何要分IP层和链路层?
网络并不是只有以太网一种,还有无线局域网,以及接入互联网的通讯线路,它们和 IP 之间的关系又是什么样的呢?
其实只要将以太网替换成无线局域网、互联网线路等通讯规格就能够了。
也就是说,若是和下一个路由器之间是经过无线局域网链接的,那么就委托无线局域网将包传输过去;
若是是经过互联网线路链接的,那么就委托它将包传输过去。
除了这里列举的例子以外,世界上还有不少其余类型的通讯技术,它们之间的关系也是同样的,都是委托所使用的通讯技术将包传输过去。
IP 自己不负责包的传输,而是委托各类通讯技术将包传输到下一个路由器,这样的设计是有重要意义的,便可以根据须要灵活运用各类通讯技术,这也是 IP 的最大特色。正是有了这一特色,咱们才可以构建出互联网这一规模巨大的网络
因此这一点再次的看出来,为何网络的通讯模型采用分层次的结构设计,经过层次的设计,IP层就专职负责总体交付就行了
每一层都可以独立发展,运用最合适的技术。

数据的接收

从网卡到操做系统     

计算机数据的一部分接收过程与路由器逻辑是如出一辙的
经过网线的光/电信号,达到计算机的网口, 转换为数字信号
会经过包的 帧校验序列(FCS) 来校验错误,若是是错误的也会丢弃
当 FCS 一致,即确认数据没有错误时,接下来须要 检查 MAC 头部 中的接收方 MAC 地址,若是是发给本身的,就缓存下来,通知操做系统进行处理
路由器此时的处理是丢掉MAC头部,而后解析IP数据报信息,而后会查找转发表开始准备转发了
而咱们的计算机操做系统做为最终目的地,固然再也不须要转发,会根据收到的MAC数据进行处理
 
网卡每收到一个MAC帧就先用硬件检查MAC帧中的目的地址。
若是是发往本站的帧则收下,而后再进行其余的处理。不然就将此帧丢弃,再也不进行其余的处理 。这样作就不浪费主机的处理机和内存资源。
这里“发往本站的帧”包括如下三种帧:
    (1)单播(unicast)帧(一对一),即收到的帧的MAC地址与本站的硬件地址相同。
    (2)广播(broadcast)帧(一对全体),即发送给本局域网上全部站点的帧(全1地址)。
    (3)多播(multicast)帧(一对多),即发送给本局域网上一部分站点的帧。
    全部的适配器都至少应当可以识别前两种帧,即可以识别单播和广播地址。有的适配器可用编程方法识别多播地址。
当操做系统启动时,它就把适配器初始化,使适配器可以识别某些多播地址。显然,只有目的地址才能使用广播地址和多播地址。
 
网卡须要经过中断将网络包到达的事件通知给 CPU以后,接下来,CPU 就会暂停当前的工做,并切换到网卡的任务。
而后,网卡驱动会开始运行,从网卡缓冲区中将接收到的包读取出来,根据 MAC头部的以太类型字段判断协议的种类,并调用负责处理该协议的软件。
这里,以太类型的值应该是表示 IP 协议,所以会调用 TCP/IP 协议栈,并将包转交给它。
 
简言之
网卡接收到数据以后,产生中断,汇报操做系统,操做系统过来读取数据,根据类型交给指定的协议栈实现部分
至此,数据已经从另外一端达到了目的地计算机了

IP模块接收

当网络包转交到协议栈时,IP 模块会首先开始工做, 检查 IP 头部
IP模块首先会检查 IP 头部的格式是否符合规范,而后检查接收方 IP 地址,看包是否是发给本身的
确认包是发给本身的以后, 接下来须要 检查包有没有被分片 
检查 IP头部的内容就能够知道是否分片,若是是分片的包,则将包暂时存放在内存中,等全部分片所有到达以后将分片组装起来还原成原始包;
若是没有分片,则直接保留接收时的样子,不须要进行重组。
到这里,咱们就完成了包的接收。
 
IP是对运输层负责的,运输层也就是TCP或者UDP
因此接下来须要 检查 IP 头部的协议号字段,并将包转交给相应的模块
例如,若是协议号为06(十六进制),则将包转交给 TCP 模块;若是是 11(十六进制),则转交给 UDP 模块。
 
简言之
协议栈的IP模块会检查IP头部,(1)    判断是否是发给本身的;(2)    判断网络包是否通过分片;(3)    将包转交给TCP模块或UDP模块。

TCP模块接收-链接

  TCP 头部中的控制位 SYN 为 1 时,表示这是一个发起链接的包
这时,TCP 模块会执行接受链接的操做
不过在此以前,须要先 检查包的接收方端口号 ,并确认在该端口上有没有与接收方端口号相同且正在处于等待链接状态的套接字。
若是指定端口号没有等待链接的套接字,则向客户端返回错误通知的包。
 
若是存在等待链接的套接字,则为这个套接字复制一个新的副本 ,并将发送方 IP 地址、端口号、序号初始值、窗口大小等必要的参数写入这个套接字中
同时分配用于发送缓冲区和接收缓冲区的内存空间。
而后生成表明接收确认的 ACK 号 ,用于从服务器向客户端发送数据的序号初始值,表示接收缓冲区剩余容量的窗口大小,并用这些信息生成 TCP 头部,委托IP 模块发送给客户端 。
这不就是上面说过的TCP的三次握手嘛,这是其中的第二步,收到“TCP 头部中的控制位 SYN 为 1 时”是第一步
这个包到达客户端以后,客户端会返回表示接收确认的 ACK 号,当这个ACK 号返回服务器后,链接操做就完成了

TCP模块接收-传输

而后就是数据的传送阶段了
数据包重复着上面的过程,TCP 模块会检查收到的包对应哪个链接
在服务器端,可能有多个已链接的套接字对应同一个端口号,所以仅根据接收方端口号没法找到特定的套接字。
这时咱们须要根据 IP 头部中的发送方 IP 地址和接收方 IP 地址,以及 TCP 头部中的接收方端口号和发送方端口号共 4 种信息,找到上述4 种信息所有匹配的套接字。
简言之,发送方 IP 地址和接收方 IP,发送方端口和接收方端口惟一肯定一条链接 (另外其实包含协议,应该是五个肯定一条链接)
找到 4 种信息所有匹配的套接字以后,TCP 模块会对比该套接字中保存的数据收发状态和收到的包的 TCP 头部中的信息是否匹配,以肯定数据收发操做是否正常。
具体来讲,就是根据保存的上一个序号和数据长度计算下一个序号
并检查与收到的包的 TCP 头部中的序号是否一致 。若是二者一致,就说明包正常到达了服务器,没有丢失。
这时,TCP模块会从包中提出数据,并存放到接收缓冲区中,与上次收到的数据块链接起来。这样一来,数据就被还原成分包以前的状态了。
 
当收到的数据进入接收缓冲区后,TCP 模块就会生成确认应答的 TCP头部,并根据接收包的序号和数据长度计算出 ACK 号,而后委托 IP 模块发送给客户端。
这将又是一条漫长的旅途同发送数据相似,不过咱们根本感受不到。

web应用程序接收

收到的数据块进入接收缓冲区,意味着数据包接收的操做告一段落了。
接下来,应用程序会调用 Socket 库的 read来获取收到的数据,这时数据会被转交给应用程序。若是应用程序不来获取数据,则数据会被一直保存在缓冲区中
但通常来讲,应用程序会在数据到达以前调用 read 阻塞式的等待数据到达,在这种状况下,TCP 模块在完成接收操做的同时,就会执行将数据转交给应用程序的操做。
 
接收到请求后,会根据URI转换为实际的文件,这些事情web服务器会进行处理
若是 URI 指定的文件内容为 HTML 文档或图片,那么只要直接将文件内容做为响应消息返回客户端就能够了。
但 URI 指定的文件内容不只限于 HTML 文档,也有多是一个程序。
在这个状况下,服务器不会直接返回文件内容,而是会运行这个程序,而后将程序输出的数据返回给客户端
而响应的内容就是HttP协议中对于响应的约束。

总结

以下图所示,数据就是这样一层层的不断进行数据封装传递。
应用层协议的软件,根据目的地的IP地址(若是是域名须要先进行DNS解析)以及端口号,再加上其余的信息按照HTTP协议组装成HTTP请求数据
而后借助于操做系统提供的Socket接口,调用TCP模块对数据进行处理,添加头部,分片等
TCP想要发送数据前,还须要创建链接,也就是Socket的链接过程,这个创建链接的过程的数据发送流程与数据传送阶段的流程相同
他们都是TCP组装好数据而后交由IP模块进行处理
IP模块根据目的地IP地址,借助于操做系统的路由表选择下一跳路由,而路由表又是根据各类路由选择协议自学习而来的
获得了下一跳的路由,再根据ARP协议就能够查询获得下一站的物理地址
应用程序借助于操做系统创建Socket链接,会分配端口,也就是源端口
此时就有了源IP地址,目的IP地址,源端口,目的端口,源MAC,目的MAC
而后操做系统与网卡驱动配合将数据封装成以太网帧,而且借助于网卡将数据转换为光电信号发送出去
 
路由器的端口有网卡和MAC,因此能够做为接收方,网卡将光电信号转换为数据,而后进行数据校验,MAC检验,确认是发给本身的
而后就根据路由表进行转发,这个路由表跟操做系统的路由表同样的逻辑原理
这一步又跟操做系统IP模块的处理差很少,找到了下一跳IP而后ARP协议查找MAC,而后更改源MAC和目的MAC
完成数据在链路层的传递
 
最终经过一段一段的链路到达目的地主机,主机的网卡相似路由器,也是光电信号转换接收,而后检验,MAC检验,而后通知操做系统
操做系统解析MAC数据报,而后IP模块接收,而后TCP/UDP,而后最终到达WEB应用程序。
这就是大体,大体的网络通讯过程。
 
参考:计算机网络(谢希仁)、网络是怎样链接的(户根勤,周自恒(译者))
相关文章
相关标签/搜索