应用层
HTTP头部包含那些信息
HTTP头部本质上是一个传递额外重要信息的键值对。主要分为:通用头部、请求头部、响应头部、实体头部
通用头部
协议头 | 说明 | 举例 |
---|---|---|
Cache-Control | 用来指定当前的请求/回复中是否使用缓存机制 | Cache-Control:no-store |
Connection | 客户端(浏览器)想要优先使用的连接类型 | Connetion: keep-alive(Upgrade) |
Date | 报文创建时间 | Date:Dec,26 2015 17:30:00 GMT |
Trailer | 会实现说明在报文主体后记录那些首部字段,该首部字段可以使用在HTTP/1.1版本分块传输编码时 | Trailer:Expiress |
Transfer-Encoding | 用来改变报文格式 | Transfer-Encoding: chunked |
Upgrade | 要求服务器升级到一个高版本协议 | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
Via | 告诉服务器,这个请求是由哪些代理发出的 | Via: 1.0 fred, 1.1 itbilu.com.com (Apache/1.1) |
Warning | 一个一般性的警告,表示在实体内容中可能存在错误 | Warning: 199 Miscellaneous warning |
请求头部
协议头 | 说明 | 举例 |
---|---|---|
Accept | 告诉服务器自己允许哪些媒体类型 | Accept: text/plain |
Accept-Charset | 浏览器申明可接受的字符集 | Accept-Charset: utf-8 |
Accept-Encoding | 浏览器申明自己接收的编码方法 | Accept-Encoding: gzip, deflate |
Accept-Language | 浏览器可接受的响应内容语言列表 | Accept-Language: en-US |
Authorization | 用于表示 HTTP 协议中需要认证资源的认证信息 | |
Expect | 表示客户端要求服务器做出特定的行为 | Expect: 100-continue |
From | 发起此请求的用户的邮件地址 | From: user@itbilu.com |
Host | 表示服务器的域名以及服务器所监听的端口号 | Host: www.itbilu.com:80 |
If-XXX | 条件请求 | If-Modified-Since: Dec, 26 Dec 2015 17:30:00 GMT |
Max-Forwards | 限制该消息可被代理及网关转发的次数 | Max-Forwards: 10 |
Range | 表示请求某个实体的一部分,字节偏移以 0 开始 | Range: bytes=500-999 |
Referer | 表示浏览器所访问的前一个页面,可以认为是之前访问页面的链接将浏览器带到了当前页面 | Referer: http://itbilu.com/nodejs |
User-Agent | 浏览器的身份标识字符串 | User-Agent: Mozilla/…… |
响应头部
协议头 | 说明 | 举例 |
---|---|---|
Accept-Ranges | 字段的值表示可用于定义范围的单位 | Accept-Ranges: bytes |
Age | 创建响应的时间 | Age:5744337 |
ETag | 唯一标识分配的资源 | Etag:W/“585cd998-7c0f” |
Location | 表示重定向后的 URL | Location: http://www.zcmhi.com/archives/94.html |
Retry-After | 告知客户端多久后再发送请求 | Retry-After: 120 |
Server | 告知客户端服务器信息 | Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) |
Vary | 缓存控制 | Vary: Origin |
实体头部
协议头 | 说明 | 举例 |
---|---|---|
Allow | 对某网络资源的有效的请求行为,不允许则返回405 | Allow: GET, HEAD |
Content-encoding | 返回内容的编码方式 | Content-Encoding: gzip |
Content-Length | 返回内容的字节长度 | Content-Length: 348 |
Content-Language | 响应体的语言 | Content-Language: en,zh |
Content-Location | 请求资源可替代的备用的另一地址 | Content-Location: /index.htm |
Content-MD5 | 返回资源的MD5校验值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 在整个返回体中本部分的字节位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 返回内容的MIME类型 | Content-Type: text/html; charset=utf-8 |
Expires | Expires | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 请求资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Keep-Alive 和非 Keep-Alive区别,对服务性能有影响么
在早期的HTTP/1.0中,浏览器每次发起请求都要与服务器创建一个新的TCP连接,服务器完成请求立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。然而创建和关闭连接的过程需要消耗资源和时间,为了减少资源消耗,缩短响应时间,就需要重用连接。在HTTP/1.1版本中默认使用持久连接,在此之前的HTTP版本的默认连接都是使用非持久连接,如果想要在旧版本的HTTP协议上维持持久连接,则需要指定connection
的首部字段的值为Keep-Alive来告诉对方这个请求响应完成后不要关闭,下次咱们还用这几个请求继续交流:
对于非 Keep=Alive 来说,必须为每一个请求的对象建立和维护一个全新的连接。对于每一个这样的连接,客户机和服务器都要分配 TCP 的缓冲区和变量,这给服务器带来的严重的负担,因为一台 Web 服务器可能同时服务于数以百计的客户机请求。在 Keep-Alive 方式下,服务器在响应后保持该 TCP 连接打开,在同一个客户机与服务器之间的后续请求和响应报文可通过相同的连接进行传送。甚至位于同一台服务器的多个 Web 页面在从该服务器发送给同一个客户机时,可以在单个持久 TCP 连接上进行。
然而,Keep-Alive 并不是没有缺点的,当长时间的保持 TCP 连接时容易导致系统资源被无效占用,若对 Keep-Alive 模式配置不当,将有可能比非 Keep-Alive 模式带来的损失更大。因此,我们需要正确地设置 keep-alive timeout 参数,当 TCP 连接在传送完最后一个 HTTP 响应,该连接会保持 keepalive_timeout 秒,之后就开始关闭这个链接。
HTTP 长连接短连接使用场景是什么
长连接:多用于操作频繁,点对点的通讯,而且客户端连接数目较少的情况。例如即时通讯、网络游戏等。
短连接:用户数目较多的Web网站的 HTTP 服务一般用短连接。例如京东,淘宝这样的大型网站一般客户端数量达到千万级甚至上亿,若采用长连接势必会使得服务端大量的资源被无效占用,所以一般使用的是短连接。
HTTP方法
http/1.0定义了三种请求方法: GET、POST和HEAD方法
http/1.1增加了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE和CONNECT方法
GET
请求指定的页面信息,并返回具体内容,通常只用于读取数据
HEAD
类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头
POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立或已有资源的更改。
PUT
替换指定的资源,没有的话就新增
DELETE
请求服务器删除URL标识的资源数据
CONNECT
将服务器作为代理,让服务器代替用户进行访问
OPTIONS
向服务发送该方法,会返回对指定资源所支持的HTTP请求方法
TRACE
回显服务器收到的请求数据,即服务器返回自己收到的数据,主要用于测试和诊断
PATCH
是对PUT方法的补充,用来对已知资源进行局部更新。
GET和POST的区别
- get提交的数据会放在URL之后,并且请求参数会被完整的保留在浏览器的记录里,由于参数直接暴露在URL中,可能会存在安全问题,因此往往用于获取资源信息。而PSOT参数放在请求主体中,并且参数不会被保留,相较于get方法,post方法更安全,主要用于修改服务器上的资源。
- get请求只支持URL编码,post请求支持多种编码格式
- get只支持ASCII字符格式的参数,而post方法没有限制
- get提交的数据大小有限制(这里所说的限制是针对浏览器而言),而POST方法的数据没限制
- get方法需要使用Request.QueryString 来去的变量的值,而post方式通过Request.From来获取。
- get方法产生一个TCP数据包,post方法产生两个(并不是所有的浏览器都产生两个)
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务端响应200,请求成功。
对于POST方式的请求,浏览器会先发送http header给服务端,告诉服务端等一下会有数据过来,服务端响应100 continue,告诉浏览器我已经准备接收数据,浏览器再post发送一个data给服务端,服务端响应200,请求成功。
GET的长度限制是多少?
URL构成:协议 + :// + 认证信息 + @ + 域名 or IP地址 + 端口号 + 资源路径 + ? + 查询字符串 + # + 片段标识符;
所以这里说整个URL 的长度,就是指包含上述所有组成部分在内的总长度,数据部分就是指查询字符串。
HTTP中的GET方法是通过URL传递数据的,而URL本身并没有对数据的长度进行限制,真正限制GET长度的是浏览器,例如IE浏览器对URL的最大限制为2000多字符,大概2KB左右。像 Chrome, FireFox 等浏览器能支持的 URL 字符数更多,其中 FireFox 中 URL 最大长度限制为 65536 个字符,Chrome 浏览器中 URL 最大长度限制为 8182 个字符。并且这个长度不是只针对数据部分,而是针对整个 URL 而言,在这之中,不同的服务器同样影响 URL 的最大长度限制。因此对于特定的浏览器,GET的长度限制不同。
由于 POST 方法请求参数在请求主体中,理论上讲,post 方法是没有大小限制的,而真正起限制
HTTP 与 HTTPs 的工作方式【建立连接的过程】
- HTTP
HTTP(Hyper Text Transfer Protocol: 超文本传输协议)是一种简单的请求—响应协议, 被用于在Web浏览器和网站服务之间传递消息。HTTP使用Tcp(而不是UDP)作为它的支撑运输层协议。其默认工作在TCP协议80端口,HTTP客户端发起一个与服务器的TCP连接,一旦连接建立。客户机从套接字接口发送HTTP请求报文和接收HTTP响应报文。类似的,服务器也是从套接字接口接收HTTP请求报文和发送HTTP响应报文。其通信内容以明文的方式发送,不通过任何方式的数据加密。当通信结束时,客户端与服务端关闭连接。
- HTTPS
HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)是以安全为目标的 HTTP 协议,在 HTTP 的基础上通过传输加密和身份认证的方式保证了传输过程的安全性。其工作流程如下:
① 客户端发起一个 HTTPS 请求,并连接到服务器的 443 端口,发送的信息主要包括自身所支持的算法列表和密钥长度等;
② 服务端将自身所支持的所有加密算法与客户端的算法列表进行对比并选择一种支持的加密算法,然后将它和其它密钥组件一同发送给客户端。
③ 服务器向客户端发送一个包含数字证书的报文,该数字证书中包含证书的颁发机构、过期时间、服务端的公钥等信息。
④ 最后服务端发送一个完成报文通知客户端 SSL 的第一阶段已经协商完成。
⑤ SSL 第一次协商完成后,客户端发送一个回应报文,报文中包含一个客户端生成的随机密码串,称为 pre_master_secre,并且该报文是经过证书中的公钥加密过的。
⑥ 紧接着客户端会发送一个报文提示服务端在此之后的报文是采用pre_master_secre 加密的。
⑦ 客户端向服务端发送一个 finish 报文,这次握手中包含第一次握手至今所有报文的整体校验值,最终协商是否完成取决于服务端能否成功解密。
⑧ 服务端同样发送与第 ⑥ 步中相同作用的报文,已让客户端进行确认,最后发送 finish 报文告诉客户端自己能够正确解密报文。
当服务端和客户端的 finish 报文交换完成之后,SSL 连接就算建立完成了,之后就进行和 HTTP 相同的通信过程,唯一不同的是在 HTTP 通信过程中并不是采用明文传输,而是采用对称加密的方式,其中对称密钥已经在 SSL 的建立过程中协商好了。
HTTP:默认用TCP协议的80端口(可以改),通信内容明文传输,不处理
HTTPS:
请求:443端口,支持算法,密钥长度
理解:两网友约定明天出去玩,玩什么呢?爬山,游泳,游乐园选一个吧
响应:选择一种,将其密钥组件一起发给客户端
理解:我们去游乐园吧
响应:数字证书
理解:为了证明我是个合法公民。给你看看我的身份证,身份证是XX公安局发的,身份证号是XX,10年后过期
响应:协商完成
理解:OK,我同意去游乐园
生成随机密码串,并使用证书公钥加密
理解:为了互相证明我们是协商的网友,每个句尾加个“喵”
请求:尝试使用加密串加密
理解:我们试试,我是客户端喵
响应:发送finish结束
理解:我说完了你试试
响应:和客户端相同进行加密发送
理解:服务端喵
HTTPS 和 HTTP 的区别
- http协议以明文方式发送内容,数据都是未加密的,安全性较差。https数据传输过程是加密的,安全性较好。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80端口,后者是443端口
- https协议需要到数字认证机构(Certificate Authority, CA)申请证书,一般需要一定的费用。
- http页面响应比https快,主要因为HTTP使用三次握手建立连接,客户端和服务器需要握手三次,而HTTPS除了TCP的3次握手,还需要经历一个SSL协商过程。
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。如今被广泛使用,如网页,电子邮件,互联网传真,即时消息和语音在IP电话(VoIP)。其中网站是通过使用TLS来保护WEB浏览器与服务器之间的通信安全。
HTTPS的加密方式
https采用对称加密和非对称假期相结合的方式,首先使用SSL/TLS协议进行加密传输,为了弥补非对称加密的缺点,https采用证书来进一步加强非对称加密的安全性,通过非对称加密,客户端和服务端协商好之后进行通信传输的对称秘钥,后续的所有信息都通过该对称秘钥进行加密解密,完成整个https的流程。
HTTP 是不保存状态的协议,如何保存用户状态
假定某个特定的客户机在短时间内两次请求同一个对象,服务器并不会因为刚刚为该用户提供了该对象不再做出反应,而是重新发送该对象,就像该服务器已经完全忘记不就之前所做过的是一样。因为一个HTTP服务器并不保存关于客户机的任何信息,所以我们说http是一个无状态协议。
基于Session实现的会话保持
在客户端第一次向服务器发送HTTP请求后,服务器会创建一个Session对象并将客户端的身份信息以键值对的形式存储下来,然后分配一个会话标识(Sessionld)客户端,这个会话标识一般保存在客户端Cookie中,之后每次该浏览器发送http请求都会带上Cookie中的Sessionld到服务器,服务器根据会话标识就可以将之前的状态信息与会话联系起来,从而实现会话保持。
优点:安全性高,因为状态信息保存在服务端
缺点:由于大型网站往往采用分布式服务器,浏览器发送的http请求一般要先通过负载均衡器才能到达具体的后台服务器,倘若同一个浏览器两次 HTTP 请求分别落在不同的服务器上时,基于 Session 的方法就不能实现会话保持了。
【解决方法:采用中间件,例如 Redis,我们通过将 Session 的信息存储在 Redis 中,使得每个服务器都可以访问到之前的状态信息】
基于Cookie实现的会话保持
当服务器发送响应消息时,在http响应头中设置Set-Cookie字段,用来存储客户端的状态信息。客户端解析出http响应头中的字段信息,并根据其生命周期创建不同的Cookie,这样一来每次浏览器发送http请求的时候都会带上Cookie字段,从而实现状态保持。基于 Cookie 的会话保持与基于 Session 实现的会话保持最主要的区别是前者完全将会话状态信息存储在浏览器 Cookie 中。
优点:服务器不用保存状态信息, 减轻服务器存储压力,同时便于服务端做水平拓展。
缺点:该方式不够安全,因为状态信息存储在客户端,这意味着不能在会话中保存机密数据。除此之外,浏览器每次发起 HTTP 请求时都需要发送额外的 Cookie 到服务器端,会占用更多带宽。
状态码
HTTP状态码由三个十进制数字组成,第一个数字定义了状态码的类型,后两个并没有起到分类作用。HTTP状态码共有5中类型。
分类
1xx:
指示信息–表示请求正在处理
2xx:
成功–表示请求已被成功处理完毕
3xx:
重定向–要完成的请求需要进行附加操作
4xx:
客户端错误–请求有语法错误或者请求无法实现,服务器无法处理请求
5xx:
服务器端错误–服务器处理请求出现错误
相应的HTTP状态码列表
100: Continue
继续,客户端继续处理请求。
101:Switching Protocol
切换协议,服务器根据客户端的请求切换到更高的协议
200:OK
请求成功。请求所希望的响应头或数据体将随此响应返回
201:Created
请求以实现,并且有一个新的资源已经依据需求而建立
202: Accepted
请求已接受,已经接受请求但还未处理完成
203:Non-Authoritative Information
非授权信息,请求成功。但返回的meta信息不再原始的服务器中,而是一个副本。
204: No Content
无内容,服务器成功处理了请求,但不需要返回任何实体内容
205:Reset Content
重置内容,与204类似,不同点是返回此状态码的响应要求请求者重置文档视图
206:Partial Content
部分内容。服务器成功处理了部分Get请求。
300:Multiple Choices
多种选择。被请求的资源有一系列可供选择的回馈信息,用户或浏览器能够自行选择一个首选地址进行重定向
301:Moved Permanently
永久移动。请求的资源已被永久地移动到新 URI,返回信息会包含新的 URI,浏览器会自动定向到新 URI
302:Found
临时移动。与 301 类似。但资源只是临时被移动,客户端应继续使用原有URI
303: See Other
查看其它地址。与301类似。使用GET和POST请求查看
304: Not Modified
未修改。如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码
305:Use Proxy
使用代理。被请求的资源必须通过指定的代理才能被访问
306: Unused
在最新版的规范中,306状态码已经不再被使用
307: Temporary Redirect
临时重定向。请求的资源现在临时从不同的URI 响应请求,与302类似
400:Bad Request
客户端请求的语法错误,服务器无法理解;请求的参数有误
401:Unauthorized
当前请求需要用户验证
402: Payment Required
该状态码是为了将来可能的需求而预留的
403: Forbidden
服务器已经理解请求,但是拒绝执行它
404:Not Found
请求失败,请求所希望得到的资源未被在服务器上发现
405: Method Not Allowed
客户端请求中的方法被禁止
406:Not Acceptable
请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体
407:Proxy Authentication Required
与401响应类似,只不过客户端必须在代理服务器上进行身份验证
408: Request Time-out
请求超时。服务器等待客户端发送的请求时间过长,超时
409:Conflict
由于和被请求的资源的当前状态之间存在冲突,请求无法完成
410: Gone
被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址
411: Length Required
服务器拒绝在没有定义 Content-Length 头的情况下接受请求
412: Precondition Failed
客户端请求信息的先决条件错误
413:Request Entity Too Large
服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围
414:Request-URI Too Large
请求的 URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务
415:Unsupported Media Type
服务器无法处理请求附带的媒体格式
416:Requested range not satisfiable
客户端请求的范围无效
417:Expectation Failed
服务器无法满足Expect的请求头信息
500:Internal Server
服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理
501:Not Implemented
服务器不支持当前请求所需要的某个功能
502:Bad Gateway
作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到无效的响应
503:Service Unavailable
由于临时的服务器维护或者过载,服务器当前无法处理请求,一段时间后可能恢复正常
504: Gateway Time-out
充当网关或代理的服务器,未及时从远端服务器获取请求
505:HTTP Version not supported
服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本
200 请求成功
204 请求成功但无内容返回
206 范围请求成功
301 永久重定向; 30(2|3|7)临时重定向,语义和实现有略微区别;
304 带if-modified-since 请求首部的条件请求,条件没有满足
400 语法错误(前端挨打)
401 需要认证信息
403 拒绝访问
404 找不到资源
412 除if-modified-since 以外的条件请求,条件未满足
500 服务器错误(后端挨打)
503 服务器宕机了(DevOps or IT 挨打)
HTTP/1.1 和 HTTP/1.0 的区别
长链接
HTTP/1.0默认浏览器和服务器之间保持短暂连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成后立即断开TCP连接。HTTP/1.1版本的默认使用的是持久连接,其支持在同一个TCP请求中传送多个HTTP请求和响应。此之前的HTTP版本的默认连接都是使用非持久连接,如果想要在旧版的HTTP协议维持持久连接,则需要指定Connection的首部字段的值为Keep-alive.
缓存处理
1.1请求头中增加了一些和缓存的相关的字段,比如IF-MATCH,可以更加灵活的控制缓存策略。
HTTP缓存
访问一个网站的时候,浏览器会向服务器请求很多资源,比如css、js这些静态文件,如果每次请求都要让服务器发送所有资源,请求多了会对服务器造成很大的压力
HTTP为了解决这个问题,就引入了缓存,缓存有两种策略:
1、强缓存:每次请求资源的时候会先去缓存里找,如果有就直接用,没有才去向服务器请求资源
2、对比缓存:每次请求资源的时候先发个消息和服务器确认一下,如果服务器返回304,说明缓存可以用,浏览器就会去缓存里寻找资源
节约带宽
1.0默认把资源相关的整个对象都发给客户端,但是可能客户端不需要所有的信息,这就浪费了带宽资源,1.1的请求头引入了Range头域,可以只请求部分资源,比如断点下载的时候可以用Range
错误通知的管理
1.1增加了一些错误的状态响应码(24个),比如410表示请求的资源已经被永远删除
Host请求头
1.0的时候每台服务器都绑定唯一的IP地址,后面出现了虚拟主机,一个服务器可以有多个虚拟主机,一起共享同一个IP地址,所以为了区分不同虚拟主机,1.1添加了host请求头部
HTTP/1.X 和 HTTP/2.0 的区别
二进制传送
之前的版本数据都是用文本传输,因为文本有多种格式,所以不能很好地适应所有的场景,2.0传送的是二进制,相当于统一了格式
多路复用
1.1虽然默认复用TCP连接,但是每个请求时串行执行的,如果前面的请求超时,后面的请求智能等待(也就是线头阻塞)2.0的时候每个请求有自己的ID,多个请求可以在同一TCP连接上并行执行,不会相互影响。
header压缩
每次进行HTTP请求响应的时候,头部里很多的字段都是重复的,在2.0中,将字段记录到一张表中,头部只需要存放字段对应的编码就行,用的时候只需要拿着编号去表里查找就行,减少传输的数据量。
服务器推送
服务器会在客户端没发起请求的时候会主动推送一些需要的资源,比如客户端请求一个html文件,服务器发送完之后会把和这个html相关的静态文件也发送给客户端,当客户端准备向服务器请求静态文件的时候,就可以直接缓存中获取,就不需要在发起请求了。
HTTP/3 了解吗
HTTP2.0存在的问题
我们知道,传统Web平台的数据传输都基于TCP协议,而TCP协议在创建之前不可以避免的需要三次握手,如果需要提高数据交互的安全性,即增加传输层安全协议(TLS),还会增加更多的握手次数。HTTP从1.0到2.0,其传输层都基于TCP协议的。即使是带来了巨大性能提升的HTTP2,也无法完全解决TCP协议存在的固有问题。此外,HTTP/2 多路复用只是减少了连接数,其队头的拥塞问题并没有完全解决,倘若 TCP 丢包率过大,则 HTTP/2 的表现将不如 HTTP/1.1。
QUIC协议
QUIC(Quick UDP Internet COnnections),直译为快速UDP网络连接,是谷歌制定的一种基于UDP的低延迟传输协议。其主要目的是解决采用传输层TCP协议存在的问题,同时满足传输层和应用层对多连接,低延迟等的需求。该协议融合了TCP,TLS,HTTP2等协议的特性,并基于 UDP传输。该协议带来的主要提升有:
低延迟连接。当客户端第一次连接服务器时,QUIC 只需要 1 RTT(Round-Trid Time)延迟就可以建立安全可靠的连接(采用 TLS 1.3 版本),相比于 TCP + TLS 的 3 次 RTT 要更加快捷。之后,客户端可以在本地缓存加密的认证信息,当再次与服务器建立连接时可以实现 0 RTT 的连接建立延迟。
QUIC 复用了 HTTP/2 协议的多路复用功能,由于 QUIC 基于 UDP,所以也避免了 HTTP/2存在的队头阻塞问题。
基于 UDP 协议的 QUIC 运行在用户域而不是系统内核,这使得 QUIC 协议可以快速的更新和部署,从而很好地解决了 TPC 协议部署及更新的困难。
QUIC 的报文是经过加密和认证的,除了少量的报文,其它所有的 QUIC 报文头部都经过了认证,报文主体经过了加密。只要有攻击者篡改 QUIC 报文,接收端都能及时发现。
具有向前纠错机制,每个数据包携带了除了本身内容外的部分其他数据包的内容,使得在出现少量丢包的情况下,尽量地减少其它包的重传次数,其通过牺牲单个包所携带的有效数据大小换来更少的重传次数,这在丢包数量较小的场景下能够带来一定程度的性能提升。
HTTP3
HTTP3是在QUIC基础上发展起来的,其底层使用UDP进行数据传输,上层仍然使用HTTP2,在UDP与HTTP2之间存在一个QUIC层,其中TLS加密过程在该层进行处理。HTTP3主要有以下几个特点:
① 使用 UDP 作为传输层进行通信;
② 在 UDP 之上的 QUIC 协议保证了 HTTP/3 的安全性。QUIC 在建立连接的过程中就完成了 TLS 加密握手;
③ 建立连接快,正常只需要 1 RTT 即可建立连接。如果有缓存之前的会话信息,则直接验证和建立连接,此过程 0 RTT。建立连接时,也可以带有少量业务数据;
④ 不和具体底层连接绑定,QUIC 为每个连接的两端分别分配了一个唯一 ID,上层连接只认这对逻辑 ID。网络切换或者断连时,只需要继续发送数据包即可完成连接的建立;
⑤ 使用 QPACK 进行头部压缩,因为 在 HTTP/2 中的 HPACK 要求传输过程有序,这会导致队头阻塞,而 QPACK 不存在这个问题。
最后我们使用一张图来清晰的表示出 HTTP 协议的发展变化:
DNS 的作用和原理
DNS(Domain Name System)
是域名系统的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,用于TCP/IP网络。
DNS的作用
通常我们有两种方式识别主机:通过主机名或者IP地址。人们喜欢便于记忆的主机名表示,而路由器则喜欢定长的、有层次结构的IP地址。为了满足这些不同的偏好,我们需要一种能够进行主机名到IP地址转换的目录服务,域名系统作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网。
DNS域名解析原理
DNS采用了分布式的设计方案,其域名空间采用一种树形的层次结构:
上图展示了 DNS 服务器的部分层次结构,从上到下依次为根域名服务器、顶级域名服务器和权威域名服务器。其实根域名服务器在因特网上有13个,大部分位于北美洲。第二层为顶级域服务器,这些服务器负责顶级域名(如 com、org、net、edu)和所有国家的顶级域名(如uk、fr、ca 和 jp)。在第三层为权威 DNS 服务器,因特网上具有公共可访问主机(例如 Web 服务器和邮件服务器)的每个组织机构必须提供公共可访问的 DNS 记录,这些记录由组织机构的权威 DNS 服务器负责保存,这些记录将这些主机的名称映射为 IP 地址。
除此之外,还有一类重要的 DNS 服务器,叫做本地 DNS 服务器。本地 DNS 服务器严格来说不在 DNS 服务器的层次结构中,但它对 DNS 层次结构是很重要的。一般来说,每个网络服务提供商(ISP) 都有一台本地 DNS 服务器。当主机与某个 ISP 相连时,该 ISP 提供一台主机的 IP 地址,该主机具有一台或多台其本地 DNS 服务器的 IP 地址。主机的本地 DNS 服务器通常和主机距离较近,当主机发起 DNS 请求时,该请求被发送到本地 DNS 服务器,它起着代理的作用,并将该请求转发到 DNS 服务器层次结构中。
以一个例子了解DNS的工作原理,假设主机A(IP地址为abc.xyz.edu.)想知道主机B的IP地址(def.mn.edu)。
主机A首先向它的本地DNS服务器发送一个DNS查询报文。该查询报文含有被转换的主机名def.mn.edu。
本地DNS服务器将该报文转发到根DNS服务器,
根DNS服务器注意到查询的ip地址前缀为edu后向本地DNS服务器返回负责edu的顶级域名服务器的IP地址列表。
该本地DNS服务器则再次向这些顶级域名服务器发送查询报文。该顶级域名服务器注意到mn.edu的前缀,并用权威域名服务器的ip地址进行相应。
通常情况下,顶级域名服务器并不总是知道每台主机的权威 DNS 服务器的 IP 地址,而只知道中间的某个服务器,该中间 DNS 服务器依次能找到用于相应主机的 IP 地址,我们假设中间经历了权威服务器 ① 和 ②,最后找到了负责 def.mn.edu 的权威 DNS 服务器 ③,之后,本地 DNS 服务器直接向该服务器发送查询报文从而获得主机 B 的IP 地址。
IP 地址的查询其实经历了两种查询方式,分别是递归查询和迭代查询。
递归查询:
如果主机所询问的本地域名服务器不知道被查询域名的ip地址,那么本地域名服务器就以DNS客户端的身份,向其他域名服务器鸡血发出查询请求报文,即替主机继续查询,而不是让主机自己进行下一步查询。
迭代查询:
当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器下一步应该找哪个域名服务器进行查询,然后让本地服务器进行后续的查询
DNS为什么用UDP
DNS既使用TCP又使用UDP
- 当进行区域传送(主域名服务器向辅助域名服务器传送变化的那部分数据)时会使用TCP,因为数据同步传送数据量比一个请求和应答的数据量要多,而TCP允许的报文长度更长,因此为了保证数据的正确性,会使用基于可靠连接的TCP。
- 当客户端向DNS服务器查询域名(域名解析)的时候,一般返回的内容不会超过UDP报文的最大长度,即512字节。用UDP传输时,不需要经过TCP三次握手的过程,从而大大提高了响应速度,但这要求域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。
socket() 套接字有哪些
套接字(Socket)是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,网络进程通信的一端就是一个套接字,不同主机上的进程便是通过套接字发送报文来进行通信。例如 TCP 用主机的 IP 地址 + 端口号作为 TCP 连接的端点,这个端点就叫做套接字。
套接字主要有以下三种类型:
流套接字(SOCK_STREAM):流套接字基于 TCP 传输协议,主要用于提供面向连接、可靠的数据传输服务。由于 TCP 协议的特点,使用流套接字进行通信时能够保证数据无差错、无重复传送,并按顺序接收,通信双方不需要在程序中进行相应的处理。
数据报套接字(SOCK_DGRAM):和流套接字不同,数据报套接字基于 UDP 传输协议,对应于无连接的 UDP 服务应用。该服务并不能保证数据传输的可靠性,也无法保证对端能够顺序接收到数据。此外,通信两端不需建立长时间的连接关系,当 UDP 客户端发送一个数据给服务器后,其可以通过同一个套接字给另一个服务器发送数据。当用 UDP 套接字时,丢包等问题需要在程序中进行处理。
原始套接字(SOCK_RAW):由于流套接字和数据报套接字只能读取 TCP 和 UDP 协议的数据,当需要传送非传输层数据包(例如 Ping 命令时用的 ICMP 协议数据包)或者遇到操作系统无法处理的数据包时,此时就需要建立原始套接字来发送。
URI(统一资源标识符)和 URL(统一资源定位符)之间的区别
URL,即统一资源定位符 (Uniform Resource Locator ),URL 其实就是我们平时上网时输入的网址,它标识一个互联网资源,并指定对其进行操作或获取该资源的方法。
从定义即可看出,URL 是 URI 的一个子集,两者都定义了资源是什么,而 URL 还定义了如何能访问到该资源。URI 是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,是绝对的。简单地说,只要能唯一标识资源的就是 URI,在 URI 的基础上给出其资源的访问方式的就是 URL。