[TOC]
物 数 网 传 会 表 应
OSI是Open System Interconnect的缩写,意为开放式系统互联
| 层 | 官方解释 | 通俗解释 |
|---|---|---|
| 应用层 | 网络进程到应用程序。针对特定应用规定各层协议、时序、表示等,进行封装 。在端系统中用软件来实现,如HTTP等 | 通信类型:电子邮件,文件传输,客户端/服务器 |
| 表示层 | 数据表示形式,加密和解密,把机器相关的数据转换成独立于机器的数据。规定数据的格式化表示 ,数据格式的转换等 | 数据格式化、代码转换、数据加密:ascill到ebcdic,bcd到binary |
| 会话层 | 主机间通讯,管理应用程序之间的会话。规定通信时序 ;数据交换的定界、同步,创建检查点等 | 开始,停止会话。维持秩序。 |
| 传输层 | 在网络的各个节点之间可靠地分发数据包。所有传输遗留问题;复用;流量;可靠(Segment) | 确保传递整个文件或消息,检查所传输的数据是正确的 |
| 网络层 | 在网络的各个节点之间进行地址分配、路由和(不一定可靠的)分发报文。路由( IP寻址);拥塞控制。(Packet) | 根据网络地址将数据路由到不同的LAN和WAN即选择最合适的路径,检查Ip地址、路由设置 |
| 数据链路层 | 一个可靠的点对点数据直链。检错与纠错(CRC码);多路访问;寻址(Frame) | 错误检测并打包,确保发送的数据未被破坏。 |
| 物理层 | 一个(不一定可靠的)点对点数据直链。定义机械特性;电气特性;功能特性;规程特性 | 电信号和布线 |
应用层、传输层、网络层、网络接口层
| 层 | 功能 | 举例 |
|---|---|---|
| 应用层 | 为操作系统或网络应用程序提供访问网络服务的接口;通过应用进程间的交互来完成特定网络应用,应用层协议定义的是应用进程间通信和交互规则。不同的网络应用层有不同的应用层协议,应用层交互的数据单元称为报文。当不同的应用进程数据通信或者数据交换时,就去调用应用层的不同协议实体,让这些实体去调用TCP或者UDP层服务来进行网络传输 | 万维网应用的HTTP协议,电子邮件的SMTP协议,支持文件传送的FTP协议 |
| 传输层 | 向两个主机中应用进程之间的通信提供通用的数据传输服务。应用进程以利用该服务传送应用层报文 | 传输控制协议TCP:提供面向连接的、可靠的数据传输服务,其数据传输的单位是报文段;用户数据报协议UDP:提供无连接的、尽最大努力的数据传输服务,不保证数据传输的可靠性,单位是用户数据报; |
| 网络层 | 网络层的主要功能是寻址和对数据报的封装以及重要的路由选择功能。 这些功能大部分都是由IP协议来完成的,再加上地址解析协议(Address Resolution Protocol,ARP)、因特网控制报文协议(Internet Control Message Protocol,ICMP)等协议从旁协助,所以IP协议是本层众多实体中的核心。 | 网际协议(Internet Protocol,IP):该协议是一个无连接的协议,主要负责将数据报从源结点转发到目的结点。也就是说,IP协议通过对每个数据报中都有的源地址和目的地址进行分析,然后进行路由选择(即选择一条到达目标的最佳路径),最后再转发到目的地。需要注意的是:IP协议只是负责对数据进行转发,并不对数据进行检查。也就是说,它不负责数据的可靠性,这样设计的主要目的是提高IP协议传送和转发数据的效率;地址解析协议(Address Resolution Protocol,ARP):该协议主要负责将TCP/IP网络中的IP地址解析和转换成计算机的物理地址,以便于物理设备(如网卡)按该地址来接收数据 ;反向地址解析协议(Reverse Address Resolution Protocol,RARP):该协议的作用与ARP的作用相反,它主要负责将设备的物理地址解析和转换成IP地址;因特网控制报文协议(Internet Control Message Protocol,ICMP):该协议主要负责发送和传递包含控制信息的数据报,这些控制信息包括哪台计算机出了什么错误、网络路由出现了什么错误等内容; |
| 数据链路层 | 两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议,数据链路层将网络层交下来IP数据报组装成数据帧,在两个相邻节点间的链路上传送帧 | 数据帧:所谓数据帧(Data frame),就是数据链路层的协议数据单元,它包括三部分:帧头,数据部分,帧尾。其中,帧头和帧尾包含一些必要的控制信息,比如同步信息、地址信息、差错控制信息等;数据部分则包含网络层传下来的数据,比如IP数据包 |
| 物理层 | 物理层上所传数据的单位是比特,确定要连接电缆的插头应当有多少根引脚,以及各条引脚应如何连接。 | 传递信息所利用的是一些物理媒体,如电缆、光缆、无线信道等,并不在物理层协议之内而是在物理层协议的下面。 |
- TCP协议是一种可靠的、面向连接的协议:保证通信主机之间有可靠的字节流传输,完成流量控制功能,协调收发双方的发送与接收速度,达到正确传输的目的
- UDP是一种不可靠、无连接的协议:其特点是协议简单、额外开销小、效率较高,但是不能保证传输是否正确,UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。
面向连接举例:两个人之间通过电话进行通信; 面向无连接举例:邮政服务,用户把信函放在邮件中期待邮政处理流程来传递邮政包裹。 显然,不可达代表不可靠。
当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下:
浏览器,用的HTTP
FlashFXP,用的FTP
Outlook,用的POP、SMTP
Putty,用的Telnet、SSH
QQ文件传输
当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下:
QQ语音
QQ视频
TFTP
HTTP协议:从Web服务器传输超文本到本地浏览器的传送协议,默认使用80端口。
FTP:文件传输协议,默认使用21端口。
SMTP:简单邮件传送协议,用于发送邮件,默认使用25号端口。
POP3:和SMTP对应,POP3用于接收邮件,默认使用110端口
Telnet:一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于DOS模式下的通信服务,默认使用23端口
DNS:域名解析服务,将域名地址转换为IP地址,默认使用53号端口。
TFTP(Trival File Transfer Protocal):简单文件传输协议,默认使用69号端口。
SNMP:简单网络管理协议,默认使用161号端口,是用来管理网络设备的。
TCP是一种面向连接的、可靠的传输层协议,通过TCP报文段进行传输,报文段分为头部和数据两个部分,头部包含了此报文段的一些基本信息,基本格式如下图:
-
源端口和目的端口:即应用程序在客户端和服务器端所对应的端口号
-
序号(seq)和确认序号(ack):是TCP可靠传输的关键部分。
- 序号:是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。
- 确认号:即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。
-
数据偏移/首部长度:表明报文段头部的长度。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。
-
保留:为将来定义新的用途保留,现在一般置0。
-
控制位:URG ACK PSH RST SYN FIN,共6个,每一个标志位表示一个控制功能,0无效,1有效
-
URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。
-
ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
-
PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
-
RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求
-
SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。
-
FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
-
-
窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小是一个16bit字段,因而窗口大小最大为65535($2^{16}-1$)。
-
校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证
-
紧急指针:指向后面是优先数据的字节,在URG标志设置了时才有效。如果URG标志没有被设置,紧急域作为填充。加快处理标示为紧急的数据段。
三次握手:TCP是通过报文段进行通信的,在建立TCP连接过程中,需要客户端和服务端总共发送3个报文段以确认连接的建立。
第一次握手:Client将标志位SYN置为1,随机产生一个序号(seq)J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手:Server接收到报文段,生成一个新的报文段发送给Client,新报文段中:SYN = 1,ACK = 1,序号(seq)= J+1,确认序号(ack) = k(k为随机生成);Server进入SYN_RCVD状态
第三次握手:Client收到报文段,对报文段进行校验(ACK是否为1,ack是否为J+1),校验通过生成一个新的报文段发送给Server:ACK = 1,ack = K+1,此时Client进入ESTABLISHED状态;Server对接收到的报文段校验,校验通过进入ESTABLISHED状态。
第一次连接请求报文由于网络节点长时间滞留了,导致延误到连接释放后的某个时间才到达 Server。这时 Server 会再次给 Client 发送确认报文(第二次握手),但是 Client 进程程序并不会理睬确认报文,因为 Client 没有发送连接请求。
现在假如没有第三次握手就会建立连接,那么这次滞后的连接请求报文就会导致 TCP 误建立连接,而 Client 却不知已经建立连接,并不会发送数据给 Server,这样 Server 就会一直处于等待状态,这样就白白浪费了 Server 的很多资源。但有了第三次握手就会避免这种问题的发生,虽然延迟的连接请求发送到了 Server,但 Client 不会处理 Server 的确认报文,也不会再次发送确认请求报文,这样 Server 就知道了 Client 并没有真正想建立连接。
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭:
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:Client收到FIN后, Client 进入 TIME-WAIT状态,此时连接还没释放,必须经过时间等待计时器设置的时间 2MSL 后,Client 才进入 CLOSED 状态。时间 MSL 叫做最长报文段寿命,RFC 793建议设为 2 分钟。也就是说 Client 需要等待2*MSL=2*2=4分钟后才可以真正关闭连接然后再去建立下一个连接,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
先说第一点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。
再说第二点,如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。
所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收,每次Client返回的ACK都会告知Server当前Client窗口的大小,Server会根据窗口的大小来控制发送数据和向前滑动。
-
客户端浏览器请求DNS服务器解析域名www.baidu.com 对应的IP地址,然后通过这个IP地址和默认端口80,和服务器建立TCP连接,连接建立之后通过TCP将HTTP会话封装成数据包。
-
在客户端的传输层,把HTTP会话请求分成报文段,添加源和目的端口(如服务器使用80端口监听客户端的请求,客户端由系统随机选择一个端口如5000,与服务器进行交换,服务器把相应的请求返回给客户端的5000端口)然后使用IP层的IP地址查找目的端。
-
在客户端的网络层,通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,主要是通过查找路由表来决定通过哪个路径到达服务器。
-
在客户端的链路层,数据包通过链路层发送到路由器,通过邻居协议查找给定IP地址的MAC地址,然后发送ARP请求查找目的地址,如果得到回应后就可以使用
ARP(地址解析协议:将ip地址解析成物理地址)的请求应答交换的IP数据包现在就可以传输了,然后发送IP数据包到达服务器的地址。
HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写
常用的请求有:get,post,update,delete,head,options。
- GET:请求读取由URL所标志的数据
- POST:给服务器添加或者更新数据
- PUT:在给定的URL下存储一个文档
- DELETE:删除给定的URL所标志的资源
- OPTIONS:服务器针对特定资源所支持的HTTP请求方法
- HEAD:向服务器索要与GET请求相一致的响应,只不过
响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息
GET一般用于获取/查询资源信息,而POST一般用于更新资源信息
- 根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。 (1).所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。 注意:这里安全的含义仅仅是指是非修改信息。 (2).幂等的意味着对同一URL的多个请求应该返回同样的结果。
- 根据HTTP规范,POST表示可能修改变服务器上的资源的请求。
- get提交数据会有大小的限制(1024k),post提交无限制
- 第一部分即为请求行,分别包括
请求方法、请求URI、HTTP版本,它们之间使用英文空格SP分隔,此外,最后是一个换行符CRLF。 - 第二部分是以
key: value形式组成的请求头。其中包括 请求头-request-header (如Host``User-AgentAccept)和 实体头-entity-header (如Content-Type``Content-Length)。每一对key: value请求头后也都有一个CRLF。 - 第三部分是固定不变的单独一行
CRLF(回车换行),用于分隔第二部分和第四部分。 - 第四部分是发送请求时带上的请求实体,即
{"name":"caijialinxx"}。命令行在第二部分中添加的Content-Type: application/json请求头,标示着第四部分是 JSON 格式的数据,只在POST请求中存在,因为GET请求并不包含任何实体
- 第一部分即为状态行,分别包括
HTTP版本、状态码、状态解释,它们之间使用英文空格SP分隔,此外,最后是一个换行符CRLF。在此报文中我们可以看到状态码是302,表示页面暂时被另一个 URI 所替代,但客户端在未来的请求中仍应使用当前请求的 URI 。 - 第二部分是以
key: value形式组成的响应头。其中包括 普通头-general-header (Connection,Date) 、 响应头-response-header (ETag,Server) 和 实体头-entity-header (Content-Type,Content-Length) 。每一对key: value请求头后也都有一个CRLF。 - 第三部分是固定不变的单独一行
CRLF,同请求报文的第三部分。 - 第四部分是响应实体。在此报文第二部分中我们可以看到
Content-Type: text/html响应头,表明第四部分是一个 HTML 文档,它有 3824 字节长度的数据。
请求头:Accept/Accept—Language/Cache-Control/Cookie/User-Agent/Date/Host/Range
返回头:Accept-Ranges/Date/Cache-Control/Content-Length
- 请求处理 用户发起一个http请求,缓存获取到URL,根据URL查找是否有匹配的副本,这个副本可能在内存中,也可能在本地磁盘。
- 新鲜度检测 如果缓存中存在所请求资源的副本,则进行新鲜度检测。新鲜度检测举个简单的例子,我们在商店买了一瓶汽水,汽水瓶上肯定会标有过期时间,我们会根据这个过期时间和现在的时间做对比,看看饮料过期了没,如果没过期,我们正常喝就行了,如果已经过期,我们肯定要找商家。其实这就是一个新鲜度检测的过程,HTTP请求的新鲜度检测流程也是这样的,HTTP发起一个请求时,发现缓存中有相应的副本,接着就会检查这个副本有没有过期,如果没有过期,直接使用。如果已经过期,则进行再验证。
- 服务器再验证 缓存中的文档过期了并不代表它和服务器上的不一样,所以这个时候就需要问问服务器,过期的这段时间里这个文档到底有没有改变。如果改变了,缓存就会获取一份新的文档副本,然后发送给客户端。如果没有改变,缓存只需要获取新的首部,包括一个新的过期时间,并对缓存中的首部更新。
- 创建响应并返回 我们希望缓存看起来就像是来自原始服务器一样,缓存将已缓存的服务器响应首部作为响应首部,发送给客户端。
扩展(缓存保质期的实现):HTTP中,通过Cache-Control首部和Expires首部为文档指定了过期时间,通过对过期时间的判断,缓存就可以知道文档是不是在保质期内。Expires首部和Cache-Control:max-age 首部都是来告诉缓存文档有没有过期,为什么需要两个响应首部来做这件简单的事情了?其实这一切都是历史原因,Expires首部是HTTP 1.0中提出来的,因为他使用的是绝对日期,如果服务端和客户端时钟不同步的话(实际上这种情况非常常见),缓存可能就会认为文档已经过了保质期。 HTTP 1.1为了修正这个问题,引入了Cache-Control:max-age 首部,这个首部使用相对时间来控制保质期。
Socket 可以理解为对 TCP、UDP 协议在程序使用层面的封装,提供出一些 api 来供程序员调用开发,这就是 Socket 最表层的含义。
- Http是一个协议,Socket是一个接口
- Http可能是基于Socket的
- Socket可以维持一个长连接,http是请求响应式,通常Socket效率高
1.1相对于1.0:
支持长连接
增加了host域
增加了Range(客户端) & Content-Range(服务端)头域,支持断点续传
Range: bytes=500-999 表示需要第 500-999 字节范围的内容
Content-Range: bytes 0-499/22400,表示当前发送的数据的范围为0-499 ,而 22400 则是文件的总大小。
返回头的区别:
HTTP/1.1 200 Ok(不使用断点续传方式) HTTP/1.1 206 Partial Content(使用断点续传方式)
2.0 相对于1.x:
- 支持多路复用
- 采用二进制分帧
- 首部压缩
- 服务器推送
HTTPS (基于安全套接字层的超文本传输协议 或者是 HTTP over SSL) 是一个 Netscape 开发的 Web 协议。 你也可以说:HTTPS = HTTP + SSL HTTPS 在 HTTP 应用层的基础上使用安全套接字层作为子层。
- 客户端给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法
- 服务器确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)
- 客户端确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给服务器
- 服务器使用自己的私钥,获取客户端丝发来的随机数(即Premaster secret)
- 客户端和服务器根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程
超文本传输协议 (HTTP) 是一个用来通过互联网传输和接收信息的协议。HTTP 使用请求/响应的过程,因此信息可在服务器间快速、轻松而且精确的进行传输。当你访问 Web 页面的时候你就是在使用 HTTP 协议,但 HTTP是不安全的,可以轻松对窃听你跟 Web服务器之间的数据传输。在很多情况下,客户和服务器之间传输的是敏感歇息,需要防止未经授权的访问。为了满足这个要求,网景公司(Netscape)推出了HTTPS,也就是基于安全套接字层的 HTTP 协议。
大多数情况下,HTTP 和 HTTPS 是相同的,因为都是采用同一个基础的协议,作为 HTTP 或 HTTPS 客户端——浏览器,设立一个连接到 Web 服务器指定的端口。当服务器接收到请求,它会返回一个状态码以及消息,这个回应可能是请求信息、或者指示某个错误发送的错误信息。系统使用统一资源定位器 URI 模式,因此资源可以被唯一指定。而 HTTPS 和 HTTP 唯一不同的只是一个协议头(https)的说明,其他都是一样的。
- 1.HTTP 的 URL 以 http:// 开头,而 HTTPS 的 URL 以 https:// 开头
- 2.HTTP 是不安全的,而 HTTPS 是安全的
- 3.HTTP 标准端口是 80 ,而 HTTPS 的标准端口是 443
- 4.在 OSI 网络模型中,HTTP 工作于应用层,而 HTTPS 工作在传输层
- 5.HTTP 无需加密,而 HTTPS 对传输的数据进行加密
- 6.HTTP 无需证书,而 HTTPS 需要认证证书
1 :继续,指示信息--表示请求已接收,继续处理
2 :成功,表示请求已被成功接收、理解、接受
3 :重定向,要完成请求必须进行更进一步的操作
4 :请求错误,客户端错误--请求有语法错误或请求无法实现
5: 服务器内部错误,服务器端错误--服务器未能实现合法的请求
**200:**请求被正常处理 **204:**请求被受理但没有资源可以返回 **206:**客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。 **301:**永久性重定向 **302:**临时重定向 **303:**与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上 **304:**发送附带条件的请求时,条件不满足时返回,与重定向无关 **307:**临时重定向,与302类似,只是强制要求使用POST方法 **400:**请求报文语法有误,服务器无法识别 **401:**请求需要认证 **403:**请求的对应资源禁止被访问 **404:**服务器无法找到对应资源 **500:**服务器内部错误 **503:**服务器正忙
端口号应该大于等于1024,因为0~1023内都被系统内部占用了。 在清单文件中添加权限<uses-permission android:name="android.permission.INTERNET" />
在Android中,TCP和UDP都是网络连接,属于耗时操作,so必须放在子线程中。
Cookie技术是客户端的解决方案:服务器在用户登陆后会按照一定规律生成的标志位,将这个标志发送给客户端,客户端存储此标志,以后请求带上此标志告诉服务器自己的身份,对于这个的理解更直观的例子就是身份证,如果把国家比喻服务器,自己必做客户端,每个人在登记户口后都可以办理身份证,身份证是由国家颁发自己保存也就是Cookie,以后无论你在何时何地只要你拿出身份证就代表你身份,当你去办理车票等信息时只需出事身份证就可证明自己; cookie的内容主要包括:名字,值,过期时间,路径和域 客户端提交个人信息后,服务端返回数据的同时会在Response Header中返回Cookie信息,客户端保存在固定的位置(Set-Cookie: 设置返回的Cookie) 客户端在下次请求的时候会在Request Header中携带Cookie信息,服务端根据Cookie确认用户身份(如:自动登陆)(Cookie: 设置上传携带的Cookie)
cookie的设置以及发送过程分为以下四步:
- 客户端发送一个http请求到服务器端
- 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
- 客户端发送一个http请求到服务器端,其中包含Cookie头部
- 服务器端发送一个http响应到客户端
-
Cookie有效期:由maxAge决定,在服务器返回cookie时已设置号对应的时间
- 正数:表示有效期 时间为 maxAge,需;序列化在磁盘中,超过时间失效
- 负数:临时Cookie 不序列化,保存在内存中,关闭浏览器失效
- 0 :表示删除该Cookie
-
Cookie的修改、删除
- 修改:创建同名的Cookie在Response中返回,覆盖原来的
- 删除:创建同名的Cookie,设置maxAge = 0,在Response中返回
Session技术是服务端的解决方案,通过服务器来保持状态;当客户端第一次请求时服务器首先检查这个客户端的请求里是否已包含了一个session标识,称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,发送给客户端,客户端储存,客户端再次发送请求的时候,会将这个Session id带上,服务器根据SessionID查找用户身份
- Session原理:服务端端每一个session维护一份会话信息数据,客户端和服务端依靠一个全局唯一标sesssion_id来访问会话信息数据
- Session创建:server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建
- session的保存:
- Cookie:一般采用Cookie保存sessionId,这样下次请求时会自定添加到Request Header,cookie的名字都是类似于SEEESIONID,比如weblogic对于web应用程序生成的cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID
- URL重写(cookie被禁止):在客户端禁止Cookie时,Cookie就无法保存SessionId和发送了,此时可以使用其他方法解决:把sessionId直接附加在URL的路径之后:http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764; 作为字符串附加在请求中:http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 与Cookie对比
- cookie:信息保存在本地容易被第三方或其他获取,发起恶意请求
- session:信息保存在服务端的内存中,本地只使用cookie保存sessionId
- sessionId的时效 服务器会设置时间限定,当超过限定时间后还收不到客户端的请求即认为失效,session会结束生命周期,此时需要重新登陆 没有储存在数据库的Session,会在服务器重启后失效 用户退出登陆的时候会发起删除session,此时服务器会删除session
- 防止session混乱 通过设置客户端的令牌来解决;在服务器每次生成一个不同的id返回给客户端,同时保存在session里,客户端提交表单时必须把这个id也返回服务器,程序首先比较返回的id与保存在session里的值是否一致,如果不一致则说明本次操作已经被提交过了
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网服务器传输超文本到本地浏览器的传送协议。HTTP 是基于 TCP/IP 协议通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。
1.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、PUT、DELETE、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
2.灵活:HTTP允许传输任意类型的数据对象。
3.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
4.无状态:**HTTP协议是无状态的,HTTP 协议自身不对请求和响应之间的通信状态进行保存。任何两次请求之间都没有依赖关系。**直观地说,就是每个请求都是独立的,与前面的请求和后面的请求都是没有直接联系的。协议本身并不保留之前一切的请求或 响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。
Http报文包括请求报文和响应报文两大部分,其中请求报文由请求行(request line)、请求头(header)、空行和请求体四个部分组成。而响应报文由状态行、响应头部、空行和响应体四个部分组成。接下来我们详细介绍下请求报文的各个部分及其作用。
POST /chapter17/user.html HTTP/1.1
以上代码中“POST ”代表请求方法,“/chapter17/user.html”表示URI,“HTTP/1.1”代表协议和协议的版本。现在比较流行的是Http1.1版本
请求头部通知服务器有关于客户端请求的信息。它包含许多有关的客户端环境和请求正文的有用信息。其中比如: Host,表示主机名,虚拟主机;Connection,HTTP/1.1增加的,使用keepalive,即持久连接,一个连接可以发多个请求;User-Agent,请求发出者,兼容性以及定制化需求。
name=tom&password=1234&realName=tomson
上面代码,承载着name、password、realName三个请求参数。
- GET 请求指定的页面信息,并返回实体主体。
- HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
- POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。
- PUT 从客户端向服务器传送的数据取代指定的文档的内容。
- DELETE 请求服务器删除指定的页面。
- GET在浏览器回退时是无害的,而POST会再次提交请求
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
- GET请求在URL中传送的参数是有长度限制的,而POST没有限制
- GET参数通过URL传递,POST放在Request body中
状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
- 1xx:指示信息--表示请求已接收,继续处理
- 2xx:成功--表示请求已被成功接收、理解、接受
- 3xx:重定向--要完成请求必须进行更进一步的操作
- 4xx:客户端错误--请求有语法错误或请求无法实现
- 5xx:服务器端错误--服务器未能实现合法的请求
比如我们平时常见两种出错的状态码:
403 Forbidden //对被请求页面的访问被禁止
404 Not Found //请求资源不存在,比如:输入了错误的URL
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。以当年的通信情况来说,因为都是些容量很小的文本传输,所以即使这样也没有多大问题。可随着 HTTP 的 普及,文档中包含大量图片的情况多了起来。比如,使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请 求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的 开销。
为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connection reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。
持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外, 减少开销的那部分时间,使 HTTP 请求和响应能够更早地结束,这样 Web 页面的显示速度也就相应提高了。 在 HTTP/1.1 中,所有的连接默认都是持久连接,但在 HTTP/1.0 内并未标准化。虽然有一部分服务器通过非 标准的手段实现了持久连接,但服务器端不一定能够支持持久连接。毫无疑问,除了服务器端,客户端也需 要支持持久连接。
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能 发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。 这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。通俗地讲,请求打包一次传输过去,响应打包一次传递回来。管线化的前提是在持久连接下。
假如当请求一个包含 10 张图片的 HTML Web 页面,与挨个连接相比,用持久连接可以让请求更快结束。 而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。客户端需要请求这十个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求,以此类推,而管道机制则是允许浏览器同时发出这十个请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。 于是在使用持久连接的情况下,某个连接上消息的传递类似于
请求1->响应1->请求2->响应2->请求3->响应3
管线化方式发送变成了类似这样:
请求1->请求2->请求3->响应1->响应2->响应3
HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何优雅降级应该是国内还不普遍使用的原因之一。
虽然 HTTP/2 提高了网页的性能,但是并不代表它已经是完美的了,HTTP/3 就是为了解决 HTTP/2 所存在的一些问题而被推出来的。
HTTP协议是HyperText Transfer Protocol(超文本传输协议)的缩写,它是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。伴随着计算机网络和浏览器的诞生,HTTP1.0也随之而来,处于计算机网络中的应用层,HTTP是建立在TCP协议之上,所以HTTP协议的瓶颈及其优化技巧都是基于TCP协议本身的特性,例如tcp建立连接的3次握手和断开连接的4次挥手以及每次建立连接带来的RTT延迟时间。
- 连接无法复用:连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对大量小文件请求影响较大(没有达到最大窗口请求就被终止)。
- HTTP/1.0传输数据时,每次都需要重新建立连接,增加延迟。
- HTTP/1.1虽然加入keep-alive可以复用一部分连接,但域名分片等情况下仍然需要建立多个connection,耗费资源,给服务器带来性能压力。
- Head-Of-Line Blocking(HOLB):导致带宽无法被充分利用,以及后续健康请求被阻塞。HOLB是指一系列包(package)因为第一个包被阻塞;当页面中需要请求很多资源的时候,HOLB(队头阻塞)会导致在达到最大请求数量时,剩余的资源需要等待其他资源请求完成后才能发起请求。
- HTTP 1.0:下个请求必须在前一个请求返回后才能发出,
request-response对按序发生。显然,如果某个请求长时间没有返回,那么接下来的请求就全部阻塞了。 - HTTP 1.1:尝试使用 pipeling 来解决,即浏览器可以一次性发出多个请求(同个域名,同一条 TCP 链接)。但 pipeling 要求返回是按序的,那么前一个请求如果很耗时(比如处理大图片),那么后面的请求即使服务器已经处理完,仍会等待前面的请求处理完才开始按序返回。所以,pipeling 只部分解决了 HOLB。
- HTTP 1.0:下个请求必须在前一个请求返回后才能发出,
如上图所示,红色圈出来的请求就因域名链接数已超过限制,而被挂起等待了一段时间。
- 协议开销大: HTTP1.x在使用时,header里携带的内容过大,在一定程度上增加了传输的成本,并且每次请求header基本不怎么变化,尤其在移动端增加用户流量。
- 安全因素:HTTP1.x在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性
因为HTTP/1.x的问题,我们会引入雪碧图、将小图内联、使用多个域名等等的方式来提高性能。不过这些优化都绕开了协议,直到2009年,谷歌公开了自行研发的 SPDY 协议,主要解决HTTP/1.1效率不高的问题。谷歌推出SPDY,才算是正式改造HTTP协议本身。降低延迟,压缩header等等,SPDY的实践证明了这些优化的效果,也最终带来HTTP/2的诞生。
SPDY 协议在Chrome浏览器上证明可行以后,就被当作 HTTP/2 的基础,主要特性都在 HTTP/2 之中得到继承。
2015年,HTTP/2 发布。HTTP/2是现行HTTP协议(HTTP/1.x)的替代,但它不是重写,HTTP方法/状态码/语义都与HTTP/1.x一样。HTTP/2基于SPDY3,专注于性能,最大的一个目标是在用户和网站间只用一个连接(connection)。
HTTP/2由两个规范(Specification)组成:
- Hypertext Transfer Protocol version 2 - RFC7540
- HPACK - Header Compression for HTTP/2 - RFC7541
HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。 HTTP / 1 的请求和响应报文,都是由起始行,首部和实体正文(可选)组成,各部分之间以文本换行符分隔。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。
接下来我们介绍几个重要的概念:
- 流:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1、2…N);
- 消息:是指逻辑上的 HTTP 消息,比如请求、响应等,由一或多个帧组成。
- 帧:HTTP 2.0 通信的最小单位,每个帧包含帧首部,至少也会标识出当前帧所属的流,承载着特定类型的数据,如 HTTP 首部、负荷,等等
HTTP/2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
在 HTTP/2 中引入了多路复用的技术。多路复用很好的解决了浏览器限制同一个域名下的请求数量的问题,同时也接更容易实现全速传输,毕竟新开一个 TCP 连接都需要慢慢提升传输速度。
大家可以通过 该链接 直观感受下 HTTP/2 比 HTTP/1 到底快了多少。
在 HTTP/2 中,有了二进制分帧之后,HTTP /2 不再依赖 TCP 链接去实现多流并行了,在 HTTP/2中:
- 同域名下所有通信都在单个连接上完成。
- 单个连接可以承载任意数量的双向数据流。
- 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。
这一特性,使性能有了极大提升:
- 同个域名只需要占用一个 TCP 连接,使用一个连接并行发送多个请求和响应,消除了因多个 TCP 连接而带来的延时和内存消耗。
- 并行交错地发送多个请求,请求之间互不影响。
- 并行交错地发送多个响应,响应之间互不干扰。
- 在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。
如上图所示,多路复用的技术可以只通过一个 TCP 连接就可以传输所有的请求数据。
在 HTTP/1 中,我们使用文本的形式传输 header,在 header 携带 cookie 的情况下,可能每次都需要重复传输几百到几千的字节。
为了减少这块的资源消耗并提升性能, HTTP/2对这些首部采取了压缩策略:
- HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;
- 首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
- 每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值
例如下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销
Server Push即服务端能通过push的方式将客户端需要的内容预先推送过去,也叫“cache push”。
可以想象以下情况,某些资源客户端是一定会请求的,这时就可以采取服务端 push 的技术,提前给客户端推送必要的资源,这样就可以相对减少一点延迟时间。当然在浏览器兼容的情况下你也可以使用 prefetch。 例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。
服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,换句话说,服务器不能随便将第三方资源推送给客户端,而必须是经过双方确认才行。
虽然 HTTP/2 解决了很多之前旧版本的问题,但是它还是存在一个巨大的问题,主要是底层支撑的 TCP 协议造成的。
上文提到 HTTP/2 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。但当这个连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1 了。
因为在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。但是对于 HTTP/1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
那么可能就会有人考虑到去修改 TCP 协议,其实这已经是一件不可能完成的任务了。因为 TCP 存在的时间实在太长,已经充斥在各种设备中,并且这个协议是由操作系统实现的,更新起来不大现实。
基于这个原因,Google 就更起炉灶搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上,HTTP/3 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC。 QUIC 虽然基于 UDP,但是在原本的基础上新增了很多功能,接下来我们重点介绍几个QUIC新功能。
- 0-RTT
通过使用类似 TCP 快速打开的技术,缓存当前会话的上下文,在下次恢复会话的时候,只需要将之前的缓存传递给服务端验证通过就可以进行传输了。0RTT 建连可以说是 QUIC 相比 HTTP2 最大的性能优势。那什么是 0RTT 建连呢?
这里面有两层含义:
1.传输层 0RTT 就能建立连接。
2.加密层 0RTT 就能建立加密连接。
上图左边是 HTTPS 的一次完全握手的建连过程,需要 3 个 RTT。就算是会话复用也需要至少 2 个 RTT。
而 QUIC 呢?由于建立在 UDP 的基础上,同时又实现了 0RTT 的安全握手,所以在大部分情况下,只需要 0 个 RTT 就能实现数据发送,在实现前向加密的基础上,并且 0RTT 的成功率相比 TLS 的会话记录单要高很多。
- 多路复用
虽然 HTTP/2 支持了多路复用,但是 TCP 协议终究是没有这个功能的。QUIC 原生就实现了这个功能,并且传输的单个数据流可以保证有序交付且不会影响其他的数据流,这样的技术就解决了之前 TCP 存在的问题。
同HTTP2.0一样,同一条 QUIC连接上可以创建多个stream,来发送多个HTTP请求,但是,QUIC是基于UDP的,一个连接上的多个stream之间没有依赖。比如下图中stream2丢了一个UDP包,不会影响后面跟着 Stream3 和 Stream4,不存在 TCP 队头阻塞。虽然stream2的那个包需要重新传,但是stream3、stream4的包无需等待,就可以发给用户。
另外QUIC 在移动端的表现也会比 TCP 好。因为 TCP 是基于 IP 和端口去识别连接的,这种方式在多变的移动端网络环境下是很脆弱的。但是 QUIC 是通过 ID 的方式去识别一个连接,不管你网络环境如何变化,只要 ID 不变,就能迅速重连上。
- 加密认证的报文
TCP 协议头部没有经过任何加密和认证,所以在传输过程中很容易被中间网络设备篡改,注入和窃听。比如修改序列号、滑动窗口。这些行为有可能是出于性能优化,也有可能是主动攻击。
但是 QUIC 的 packet 可以说是武装到了牙齿。除了个别报文比如 PUBLIC_RESET 和 CHLO,所有报文头部都是经过认证的,报文 Body 都是经过加密的。
这样只要对 QUIC 报文任何修改,接收端都能够及时发现,有效地降低了安全风险。
如上图所示,红色部分是 Stream Frame 的报文头部,有认证。绿色部分是报文内容,全部经过加密。
- 向前纠错机制
QUIC协议有一个非常独特的特性,称为向前纠错 (Forward Error Correction,FEC),每个数据包除了它本身的内容之外,还包括了部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。向前纠错牺牲了每个数据包可以发送数据的上限,但是减少了因为丢包导致的数据重传,因为数据重传将会消耗更多的时间(包括确认数据包丢失、请求重传、等待新数据包等步骤的时间消耗)
假如说这次我要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。当出现其中的非校验包丢包的情况时,可以通过另外三个包计算出丢失的数据包的内容。当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。
- HTTP/1.x 有连接无法复用、队头阻塞、协议开销大和安全因素等多个缺陷
- HTTP/2 通过多路复用、二进制流、Header 压缩等等技术,极大地提高了性能,但是还是存在着问题的
- QUIC 基于 UDP 实现,是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议
在HTTP协议中有可能存在信息窃听或身份伪装等安全问题。使用HTTPS通信机制可以有效地防止这些问题。本文我们就了解一下HTTPS。
HTTPS,是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。
经常会在Web的登录页面和购物结算界面等使用HTTPS通信。使用HTTPS通信时,不再用http://,而是改用https://。另外,当浏览器访问HTTPS通信有效的Web网站时,浏览器的地址栏内会出现一个带锁的标记。对HTTPS的显示方式会因浏览器的不同而有所改变。
- HTTP 是明文传输,HTTPS 通过 SSL\TLS 进行了加密
- HTTP 的端口号是 80,HTTPS 是 443
- HTTPS 需要到 CA 申请证书,一般免费证书很少,需要交费
- HTTPS 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。
为什么说HTTPS比较安全了,接下我们介绍下HTTP存在哪些问题?
由于HTTP本身不具备加密的功能,所以也无法做到对通信整体(使用HTTP协议通信的请求和响应的内容)进行加密。即,HTTP报文使用明文(指未经过加密的报文)方式发送。
此外互联网是由联通世界各个地方的网络设施组成,所有发送和接收经过某些设备的数据都可能被截获或窥视。例如大家都熟悉的抓包工具:Wireshark,它可以获取HTTP协议的请求和响应的内容,并对其进行解析。即使经过加密处理,就有可能让人无法破解报文信息的含义,但加密处理后的报文信息本身还是会被看到的。
HTTP协议中的请求和响应不会对通信方进行确认。在HTTP协议通信时,由于不存在确认通信方的处理步骤,任何人都可以发起请求。另外,服务器只要接收到请求,不管对方是谁都会返回一个响应(但也仅限于发送端的IP地址和端口号没有被Web服务器设定限制访问的前提下)
HTTP协议的实现本身非常简单,不论是谁发送过来的请求都会返回响应,因此不确认通信方,会存在以下各种隐患。比如目标的Web服务器有可能是已伪装的Web服务器。
所谓完整性是指信息的准确度。若无法证明其完整性,通常也就意味着无法判断信息是否准确。由于HTTP协议无法证明通信的报文完整性,因此,在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉。 换句话说,没有任何办法确认,发出的请求/响应和接收到的请求/响应是前后相同的。
HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL(Secure Socket Layer)和TLS(Transport Layer Security)协议代替而已。
通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP。
在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。也就是说HTTP加上加密处理和认证以及完整性保护后即是HTTPS。
HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
这种方式加密和解密同用一个密钥。加密和解密都会用到密钥。没有密钥就无法对密码解密,反过来说,任何人只要持有密钥就能解密了。
以对称加密方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,如果通信被监听那么密钥就可会落人攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。
公开密钥加密使用一对非对称的密钥。一把叫做私有密钥,另一把叫做公开密钥。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。
使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。
非对称加密的特点是信息传输一对多,服务器只需要维持一个私钥就能够和多个客户端进行加密通信,但服务器发出的信息能够被所有的客户端解密,且该算法的计算复杂,加密速度慢。
尽管非对称加密设计奇妙,但它加解密的效率比对称加密要慢多了。那我们就将对称加密与非对称加密结合起来,充分利用两者各自的优势,将多种方法组合起来用于通信。在交换密钥环节使用非对称加密方式,之后的建立通信交换报文阶段则使用对称加密方式。具体做法是:发送密文的一方使用对方的公钥进行加密处理“对称的密钥”,然后对方用自己的私钥解密拿到“对称的密钥”,这样可以确保交换的密钥是安全的前提下,使用对称加密方式进行通信。所以,HTTPS采用对称加密和非对称加密两者并用的混合加密机制。
网络传输过程中需要经过很多中间节点,虽然数据无法被解密,但可能被篡改,那如何校验数据的完整性呢?----校验数字签名。
数字签名有两种功效:
- 能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。
- 数字签名能确定消息的完整性,证明数据是否未被篡改过。
校验数字签名流程见下图:
数字签名技术就是对“非对称密钥加解密”和“数字摘要“两项技术的应用,它将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
非对称加密方式还是存在一些问题的。那就是无法证明公开密钥本身就是货真价实的公开密钥。比如,正准备和某台服务器建立公开密钥加密方式下的通信时,如何证明收到的公开密钥就是原本预想的那台服务器发行的公开密钥。 为了解决上述问题,可以使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书。
数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。我们来介绍一下数字证书认证机构的业务流程。首先,服务器的运营人员向数字证书认证机构提出公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。 服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行非对称加密方式通信。公钥证书也可叫做数字证书或直接称为证书。
接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二,服务器的公开密钥是值得信赖的。
既然HTTPS那么安全可靠,那为何所有的Web网站不一直使用HTTPS?
其中一个原因是,因为与纯文本通信相比,加密通信会消耗更多的CPU及内存资源。如果每次通信都加密,会消耗相当多的资源,平摊到一台计算机上时,能够处理的请求数量必定也会随之减少。 因此,如果是非敏感信息则使用HTTP通信,只有在包含个人信息等敏感数据时,才利用HTTPS加密通信。 特别是每当那些访问量较多的Web网站在进行加密处理时,它们所承担着的负载不容小觑。
除此之外,想要节约购买证书的开销也是原因之一。要进行HTTPS通信,证书是必不可少的。而使用的证书必须向认证机构(CA)购买。
TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP,本文将介绍下这两者以及它们之间的区别。
TCP/IP网络模型
计算机与网络设备要相互通信,双方就必须基于相同的方法。比如,如何探测到通信目标、由哪一边先发起通信、使用哪种语言进行通信、怎样结束通信等规则都需要事先确定。不同的硬件、操作系统之间的通信,所有的这一切都需要一种规则。而我们就把这种规则称为协议(protocol)。
TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的协议。
TCP/IP模型是互联网的基础,它是一系列网络协议的总称。这些协议可以划分为四层,分别为链路层、网络层、传输层和应用层。
- 链路层:负责封装和解封装IP报文,发送和接受ARP/RARP报文等。
- 网络层:负责路由以及把分组报文发送给目标网络或主机。
- 传输层:负责对报文进行分组和重组,并以TCP或UDP协议格式封装报文。
- 应用层:负责向用户提供应用程序,比如HTTP、FTP、Telnet、DNS、SMTP等。
在网络体系结构中网络通信的建立必须是在通信双方的对等层进行,不能交错。 在整个数据传输过程中,数据在发送端时经过各层时都要附加上相应层的协议头和协议尾(仅数据链路层需要封装协议尾)部分,也就是要对数据进行协议封装,以标识对应层所用的通信协议。接下去介绍TCP/IP 中有两个具有代表性的传输层协议——TCP 和 UDP。
UDP
UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。
它有以下几个特点:
1、面向无连接
首先 UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。
具体来说就是:
- 在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头标识下是 UDP 协议,然后就传递给网络层了;
- 在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头就传递给应用层,不会任何拼接操作。
2、有单播,多播,广播的功能
UDP 不止支持一对一的传输方式,同样支持一对多、多对多、多对一的方式,也就是说 UDP 提供了单播、多播、广播的功能。
3、UDP是面向报文的
发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文。
4、不可靠性
首先不可靠性体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠。并且收到什么数据就传递什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了。
再者网络环境时好时坏,但是 UDP 因为没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP。
UDP只会把想发的数据报文一股脑的丢给对方,并不在意数据有无安全完整到达。
5、头部开销小,传输数据报文时是很高效的
UDP 头部包含了以下几个数据:
- 两个十六位的端口号,分别为源端口(可选字段)和目标端口;
- 整个数据报文的长度;
- 整个数据报文的检验和(IPv4 可选 字段),该字段用于发现头部信息和数据中的错误。
因此 UDP 的头部开销小,只有八字节,相比 TCP 的至少二十字节要少得多,在传输数据报文时是很高效的。
TCP
当一台计算机想要与另一台计算机通讯时,两台计算机之间的通信需要畅通且可靠,这样才能保证正确收发数据。例如,当你想查看网页或查看电子邮件时,希望完整且按顺序查看网页,而不丢失任何内容。当你下载文件时,希望获得的是完整的文件,而不仅仅是文件的一部分,因为如果数据丢失或乱序,都不是你希望得到的结果,于是就用到了TCP。
TCP协议全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的RFC 793定义。TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,你可以把它想象成排水管中的水流。
1、TCP连接过程
如下图所示,可以看到建立一个TCP连接的过程为(三次握手的过程):
- **第一次握手:**客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状态。
- **第二次握手:**服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态。
- **第三次握手:**当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。
这里可能大家会有个疑惑:为什么 TCP 建立连接需要三次握手,而不是两次?这是因为这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。
2、TCP断开链接
TCP 是全双工的,在断开连接时两端都需要发送 FIN 和 ACK。
- **第一次握手:**若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求。
- **第二次握手:**B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明 A 到 B 的连接已经释放,不再接收 A 发的数据了。但是因为 TCP 连接是双向的,所以 B 仍旧可以发送数据给 A。
- **第三次握手:**B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入 LAST-ACK 状态。
- **第四次握手:**A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态。当 B 收到确认应答后,也便进入 CLOSED 状态。
3、TCP协议的特点
- **面向连接:**面向连接,是指发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”,这样能建立可靠的连接。建立连接,是为数据的可靠传输打下了基础。
- **仅支持单播传输:**每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式。
- **面向字节流:**TCP不像UDP一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输。
- **可靠传输:**对于可靠传输,判断丢包,误码靠的是TCP的段编号以及确认号。TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
- **提供拥塞控制:**当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞。
- **TCP提供全双工通信:**TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)。
TCP和UDP的比较
1、对比
2、总结
- TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。
- 虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为。
- 对数据准确性要求高,速度可以相对较慢的,可以选用TCP。
打开浏览器从输入网址到网页呈现在大家面前,背后到底发生了什么?经历怎么样的一个过程?先给大家来张总体流程图,具体步骤请看下文分解!
总体来说分为以下几个过程:
- DNS 解析:将域名解析成 IP 地址
- TCP 连接:TCP 三次握手
- 发送 HTTP 请求
- 服务器处理请求并返回 HTTP 报文
- 浏览器解析渲染页面
- 断开连接:TCP 四次挥手
URL(Uniform Resource Locator),统一资源定位符,用于定位互联网上资源,俗称网址。
比如 http://www.w3school.com.cn/html/index.asp,遵守以下的语法规则:
scheme://host.domain:port/path/filename 各部分解释如下: scheme - 定义因特网服务的类型。常见的协议有 http、https、ftp、file,其中最常见的类型是 http,而 https 则是进行加密的网络传输。 host - 定义域主机(http 的默认主机是 www) domain - 定义因特网域名,比如 w3school.com.cn port - 定义主机上的端口号(http 的默认端口号是 80) path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。 filename - 定义文档/资源的名称
在浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到对应的服务器,而是要通过 IP 地址。大家这里或许会有个疑问----计算机既可以被赋予 IP 地址,也可以被赋予主机名和域名。比如 www.hackr.jp。那怎么不一开始就赋予个 IP 地址?这样就可以省去解析麻烦。我们先来了解下什么是 IP 地址
IP 地址是指互联网协议地址,是 IP Address 的缩写。IP 地址是 IP 协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。IP 地址是一个 32 位的二进制数,比如 127.0.0.1 为本机 IP。 域名就相当于 IP 地址乔装打扮的伪装者,带着一副面具。它的作用就是便于记忆和沟通的一组服务器的地址。用户通常使用主机名或域名来访问对方的计算机,而不是直接通过 IP 地址访问。因为与 IP 地址的一组纯数字相比,用字母配合数字的表示形式来指定计算机名更符合人类的记忆习惯。但要让计算机去理解名称,相对而言就变得困难了。因为计算机更擅长处理一长串数字。为了解决上述的问题,DNS 服务应运而生。
DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务。DNS 是一个网络服务器,我们的域名解析简单来说就是在 DNS 上记录一条信息记录。
例如 baidu.com 220.114.23.56(服务器外网IP地址)80(服务器端口号)
- 浏览器缓存:浏览器会按照一定的频率缓存 DNS 记录。
- 操作系统缓存:如果浏览器缓存中找不到需要的 DNS 记录,那就去操作系统中找。
- 路由缓存:路由器也有 DNS 缓存。
- ISP 的 DNS 服务器:ISP 是互联网服务提供商(Internet Service Provider)的简称,ISP 有专门的 DNS 服务器应对 DNS 查询请求。
- 根服务器:ISP 的 DNS 服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(DNS 服务器先问根域名服务器.com 域名服务器的 IP 地址,然后再问.baidu 域名服务器,依次类推)
浏览器通过向 DNS 服务器发送域名,DNS 服务器查询到与域名相对应的 IP 地址,然后返回给浏览器,浏览器再将 IP 地址打在协议上,同时请求参数也会在协议搭载,然后一并发送给对应的服务器。接下来介绍向服务器发送 HTTP 请求阶段,HTTP 请求分为三个部分:TCP 三次握手、http 请求响应信息、关闭 TCP 连接。
在客户端发送数据之前会发起 TCP 三次握手用以同步客户端和服务端的序列号和确认号,并交换 TCP 窗口大小信息。
- 客户端发送一个带 SYN=1,Seq=X 的数据包到服务器端口(第一次握手,由浏览器发起,告诉服务器我要发送请求了)
- 服务器发回一个带 SYN=1, ACK=X+1, Seq=Y 的响应包以示传达确认信息(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)
- 客户端再回传一个带 ACK=Y+1, Seq=Z 的数据包,代表“握手结束”(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)
谢希仁著《计算机网络》中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
TCP 三次握手结束后,开始发送 HTTP 请求报文。
请求报文由请求行(request line)、请求头(header)、请求体四个部分组成,如下图所示:
- 请求方法包含 8 种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
- URL 即请求地址,由 <协议>://<主机>:<端口>/<路径>?<参数> 组成
- 协议版本即 http 版本号
POST /chapter17/user.html HTTP/1.1
以上代码中“POST”代表请求方法,“/chapter17/user.html”表示 URL,“HTTP/1.1”代表协议和协议的版本。现在比较流行的是 Http1.1 版本
请求头部通知服务器有关于客户端请求的信息。它包含许多有关的客户端环境和请求正文的有用信息。其中比如:Host,表示主机名,虚拟主机;Connection,HTTP/1.1 增加的,使用 keepalive,即持久连接,一个连接可以发多个请求;User-Agent,请求发出者,兼容性以及定制化需求。
name=tom&password=1234&realName=tomson
上面代码,承载着 name、password、realName 三个请求参数。
服务器是网络环境中的高性能计算机,它侦听网络上的其他计算机(客户机)提交的服务请求,并提供相应的服务,比如网页服务、文件下载服务、邮件服务、视频服务。而客户端主要的功能是浏览网页、看视频、听音乐等等,两者截然不同。 每台服务器上都会安装处理请求的应用——web server。常见的 web server 产品有 apache、nginx、IIS 或 Lighttpd 等。
web server 担任管控的角色,对于不同用户发送的请求,会结合配置文件,把不同请求委托给服务器上处理相应请求的程序进行处理(例如 CGI 脚本,JSP 脚本,servlets,ASP 脚本,服务器端 JavaScript,或者一些其它的服务器端技术等),然后返回后台程序处理产生的结果作为响应。
后台开发现在有很多框架,但大部分都还是按照 MVC 设计模式进行搭建的。
MVC 是一个设计模式,将应用程序分成三个核心部件:模型(model)-- 视图(view)--控制器(controller),它们各自处理自己的任务,实现输入、处理和输出的分离。
1、视图(view)
它是提供给用户的操作界面,是程序的外壳。
2、模型(model)
**模型主要负责数据交互。**在 MVC 的三个部件中,模型拥有最多的处理任务。一个模型能为多个视图提供数据。
3、控制器(controller)
**它负责根据用户从"视图层"输入的指令,选取"模型层"中的数据,然后对其进行相应的操作,产生最终结果。**控制器属于管理者角色,从视图接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示模型处理返回的数据。 这三层是紧密联系在一起的,但又是互相独立的,每一层内部的变化不影响其他层。每一层都对外提供接口(Interface),供上面一层调用。 至于这一阶段发生什么?简而言之,首先浏览器发送过来的请求先经过控制器,控制器进行逻辑处理和请求分发,接着会调用模型,这一阶段模型会获取 redis db 以及 MySQL 的数据,获取数据后将渲染好的页面,响应信息会以响应报文的形式返回给客户端,最后浏览器通过渲染引擎将网页呈现在用户面前。
响应报文由响应行(request line)、响应头部(header)、响应主体三个部分组成。如下图所示:
(1) 响应行包含:协议版本,状态码,状态码描述
状态码规则如下: 1xx:指示信息--表示请求已接收,继续处理。 2xx:成功--表示请求已被成功接收、理解、接受。 3xx:重定向--要完成请求必须进行更进一步的操作。 4xx:客户端错误--请求有语法错误或请求无法实现。 5xx:服务器端错误--服务器未能实现合法的请求。
(2) 响应头部包含响应报文的附加信息,由 名/值 对组成
(3) 响应主体包含回车符、换行符和响应返回数据,并不是所有响应报文都有响应数据
浏览器拿到响应文本 HTML 后,接下来介绍下浏览器渲染机制
浏览器解析渲染页面分为一下五个步骤:
- 根据 HTML 解析出 DOM 树
- 根据 CSS 解析生成 CSS 规则树
- 结合 DOM 树和 CSS 规则树,生成渲染树
- 根据渲染树计算每一个节点的信息
- 根据计算好的信息绘制页面
- 根据 HTML 的内容,将标签按照结构解析成为 DOM 树,DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点。
- 在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。
- 解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪。
- 浏览器在 CSS 规则树生成之前不会进行渲染。
- DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树。
- 精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度。
- 布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸
- 回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。
- 绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。
- 重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。
- 回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。
当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。
- 发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)
- 被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)
- 被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)
- 发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)












