noteless 阅读(16) 评论(0)

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

这一过程涉及宽带接入、浏览器、前端技术,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,客户端与服务器相互进行数据传送
下图假设客户端无数据发送,请求断开连接