美文网首页
iOS 网络相关

iOS 网络相关

作者: ProgramDouglas | 来源:发表于2020-05-13 23:31 被阅读0次

    1、TCP/IP 及三次握手

    通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作的。而 HTTP 属于它的一个子集。
    协议:不同的硬件设备、操作系统之间需要通信的话需要遵循相同的规则,这种规则统称为 协议(protocol)。
    把与互联网相关联的协议集合起来总称为 TCP/IP 协议族。
    
    TCP/IP 协议族分为 4 层,从上到下分别是:应用层、传输层、网络层和数据链路层。
    应用层:应用层决定了向用户提供服务时通信的活动。FTP、DNS 和 HTTP 都属于此层
    传输层:传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。TCP(传输控制协议) 和 UDP(用户数据报协议) 属于传输层
    网络层:网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输线路)到达对方计算机,并把数据包传送给对方。
    链路层:用来处理连接网络的硬件部分,包括控制操作系统、硬件的设备驱动和光纤等。硬件上的范畴均在链路层的作用范围之内。
    
    1、发送端的客户端在在应用层发送一个 HTTP 请求
    2、在传输层(TCP协议)把应用层处收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号转发给网络层
    3、在网络层(IP协议),增加作为通信目的地的 MAC 地址后转发给链路层
    4、接收端的服务器在链路层收到数据后,按顺序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的 HTTP 请求
    总结:发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
    
    TCP vs UDP
    TCP为传输控制层协议,为面向连接、可靠的、点到点的通信;
    UDP为用户数据报协议,非连接的不可靠的点到多点的通信;
    TCP侧重可靠传输,UDP侧重快速传输。
    TCP首部开销20字节;UDP的首部开销小,只有8个字节(TCP要求系统资源较多,UDP较少)
    应用场景
    当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用(HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议)
    当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP(QQ语音、QQ视频、实时游戏)
    
    三次握手
    第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
    第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN+RECV状态;
    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次状态
    
    为什么要四次分手
    TCP是全双工模式.
    当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了; 但是,这个时候主机1还是可以接受来自主机2的数据;
    当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;
    当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了
    愉快的中断这次TCP连接。
    
    

    2、socket编程

    Scoket连接和HTTP连接的区别:
    HTTP协议是基于TCP连接的,是应用层协议,主要解决如何包装数据。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
    HTTP连接:短连接,客户端向服务器发送一次请求,服务器响应后连接断开,节省资源。服务器不能主动给客户端响应(除非采用HTTP长连接技术),iPhone主要使用类NSURLConnection。
    Socket连接:长连接,客户端跟服务器端直接使用Socket进行连接,没有规定连接后断开,因此客户端和服务器段保持连接通道,双方可以主动发送数据,一般多用于游戏.Socket默认连接超时时间是30秒,默认大小是8K(理解为一个数据包大小)。
    
    
    

    3、HTTP(图解HTTP

    HTTP请求报文是由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成。
    HTTP响应报文中由协议版本、状态码(表示请求成功或者失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主体
    
    HTTP/1.1 是无状态协议,协议自身不具备保存之前发送过的请求或者响应的功能。但是为了实现期望的保持状态的功能,于是引入了 Cookie 技术。
    
    告知服务器意图的 HTTP 方法
    GET:获取资源
    POST:传输实体主体。
    PUT:传输文件(鉴于 HTTP/1.1 的 PUT 方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的 Web 网站不使用此方法。)
    DELETE:删除文件。DELETE 方法是和 PUT 相反的方法,按照请求中指定的 URI,删除指定的资源。(和PUT一样有安全性问题)
    
    GET和POST的区别是什么?
    * GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密。
    POST把提交的数据则放置在是HTTP包的包体中。Request Body.
    get安全性低,post安全性较高
    * get传送的数据量较小,post传送的数据量较大,一般被默认不受限制.
    * GET书签可收藏/能被缓存/历史参数保留在浏览器历史,POST为书签不可收藏/不能缓存/参数不会保存在浏览器历史中。
    * 引入幂等主要是为了处理同一个请求重复发送的情况,比如在请求响应前失去连接,如果方法是幂等的,就可以放心地重发一次请求。这也是浏览器在后退/刷新时遇到POST会给用户提示的原因:POST语义不是幂等的,重复请求可能会带来意想不到的后果
    
    http的post和get啥区别?
    get请求可以直接以浏览器访问,post则不能;
    post可以往body里面填更多的数据,get则不能;
    浏览器一般会限制get的URL长度,无法传递较大数据,一般限制1024Byte?
    服务端对这两个请求的处理也不一样;
    post安全性稍微高一点,主要是数据没有放在url上;
    
    持久连接节省通信量
    持久连接:旨在建立1次 TCP 连接后进行多次请求和响应的交互。
    其特点是:只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。持久连接的好处在于减少了 TCP 连接的重复建立和断开造成的额外开销,减轻了服务器端的负载。
    持久化连接使得多数请求以 管线化 方式发送成为可能。这样就可以做到同时并行发送多个请求。
    
    Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
    服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
    
    HTTP 状态码
    200 OK:表示客户端发来的请求在服务器端被正常处理了。
    301 Moved Permanently:永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后应使用资源现在所指定的 URI。
    302 FOUND:临时性重定向。该状态码表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。
    400 Bad Request:该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容再次发送请求。
    403 Forbidden:该状态码表明对请求资源的访问被服务器拒绝了。
    404 Not Found:该状态码表明服务器上无法找到请求的资源。
    500 Internal Server Error:该状态码表明服务器端在执行请求时发生了错误。
    
    HTTP 过程:
    1. 建立TCP连接,3次握手
    2. Web浏览器向Web服务器发送请求命令 (例如:GET/sample/hello.jsp HTTP/1.1)
    3. Web浏览器发送请求头信息 (User-Agent、Host、Cookie等信息,以空行结束)
    4. Web服务器应答 ( HTTP/1.1 200 OK)
    5. Web服务器发送应答头信息 (1. 响应头(response header) 2. 普通头(general header) 3. 实体头(entity header))
    6. Web服务器向浏览器发送数据 (服务器返回给客户端的文本信息)
    7. Web服务器关闭TCP连接
    
    

    从输入URL到页面加载发生了什么

    image.png

    1、当用户需要请求github.com的时候,首先要打开浏览器,输入URL地址,即输入github.com
    2、浏览器发起 DNS 调用去解析URL中的域名字段:
    先检查本地缓存中有没有这个域名
    如果有,浏览器将接收到的URL中抽取出域名字段,就是访问的主机名,比如https://github.com,并将这个主机名传送给DNS应用的客户端
    如果没有查找系统hosts文件有没有这个域名,如果有,解析出IP
    如果没有,DNS客户机端向DNS服务器端发送一份查询报文,报文中包含着要访问的主机名字段
    该DNS客户机最终会收到一份回答报文,其中包含有该主机名对应的IP地址
    3、一旦该浏览器收到来自DNS的IP地址,就可以向该IP地址定位的HTTP服务器发起TCP连接
    浏览器先通过本地随机端口去建立一个通向服务端的连接通道,此通道遵循HTTP协议
    浏览器将客户端信息打“包”
    将“包”通过连接通道发送到服务端
    4、服务端接收并打开这个“包”,读取到里面的请求路径
    5、根据文件请求路径找到MIME-TYPE,即获得了消息内容类型
    6、判断这个文件是否为静态文件,如果是静态文件,自己处理,如果自己不能处理,交给自己服务中的其他“小弟们”处理
    7、如果是静态文件,则读取静态文件内容,将内容返回给客户端
    8、如果不是静态文件,则发送给“小弟”处理,这里假设PHP能处理,就按照PHP的语法规则去处理并返回给服务端
    9、服务端将处理好的数据以及其他一些内容,打“包”并通过之前建立的通道发送给客户端
    10、客户端接收并打开这个服务端发送回来的“包”,找到其中的Content-Type
    11、根据Content-Type指定的编码格式(例如html,css,javascript等),决定怎么去处理这些文件或者渲染网页
    12、假设是HTML,则直接渲染到网页结构上

    4、HTTP- Range

    场景一:断点续传/下载。在下载软件时,已经下载了 95% 了,此时网络断了,如果不支持范围请求,那就只有被迫重头开始下载。但是如果有范围请求的加持,就只需要下载最后 5% 的资源,避免重新下载。
    场景二:多线程下载,对大型文件,开启多个线程,每个线程下载其中的某一段,最后下载完成之后,在本地拼接成一个完整的文件,可以更有效的利用资源。

    发送请求,获取资源。
    响应请求,头部有 Accept-Ranges:bytes 来标记的,有此标记标识当前资源支持范围请求。
    请求头部,Ranges来指定请求实体的范围。它的范围取值是在 0 - Content-Length 之间,使用 - 分割
    响应头部,Content-Ragne标记响应的实体内容范围。标记它的单位是 bytes 然后标记当前传递的内容实体范围和总长度。

    在 HTTP 的范围请求中,可以使用ETag或者 Last-Modified 来区分分段请求的资源,是否有修改过,只需要在请求头中,将它放在 If-Range 这个请求报文头中即可。如果两次操作的都是同一个资源文件,就会继续返回 206 状态码,开始后续的操作,反之则会返回 200 状态码,表示文件发生改变,要从头下载。

    image.png

    5、HTTP & HTTPS- 中间人攻击(什么是中间人攻击?如何避免?

    中间人攻击是指攻击者与通讯的两端分别创建独立的联系,在请求和响应传输途中,拦截并篡改内容。通讯的两端都误以为他们正在通过一个私密的连接与对方直接对话。
    对于 HTTP 来说,由于设计的简单,不需要太多步骤就可以进行监听和修改报文;而HTTPS 使用了 SSL 加密协议,是一种非常安全的机制,目前并没有方法直接对这个协议进行攻击,一般都是在建立 SSL 连接时,利用中间人获取到 CA证书、非对称加密的公钥、对称加密的密钥;有了这些条件,就可以对请求和响应进行拦截和篡改。

    中间人攻击需要截获请求响应

    对于中间人攻击,有一个前提就是:需要截获到客户端与服务器通信的线路。

    抓包工具一般都是用户主动将其设置成系统的网络访问代理服务器,使得所有的网络访问请求都通过它来完成,从而实现了网络封包的截取和分析。

    对于其它工具则是利用 DNS欺骗、ARP投毒、劫持网关等手段,将客户端的请求重定向到攻击者的机器,以便进行网络抓包。

    SSL 证书欺骗攻击

    SSL 证书欺骗攻击流程大概如下:

    1. 截获客户端与服务器通信的通道
    2. 然后在 SSL 建立连接的时候,进行中间人攻击
    3. 将自己伪装成客户端,获取到服务器真实有效的 CA 证书(非对称加密的公钥)
    4. 将自己伪装成服务器,获取到客服端的之后通信的密钥(对称加密的密钥)
    5. 有了证书和密钥就可以监听之后通信的内容了
    image image

    这个避免方法就是:

    • 客户端不要轻易信任证书
    • App 可以提前预埋证书在本地

    SSL 剥离攻击

    SSL 剥离就是将客户端的 HTTPS 请求降级成 HTTP 请求,阻止 HTTP 请求重定向成 HTTPS ,流程图如下:

    image

    总结

    中间人攻击主要是伪装身份,然后截取通信的内容,对于 HTTP 是可以很轻松的截获;但是对于 HTTPS,主要是在建立 SSL 连接的时候,骗取到证书和密钥;流程不是很复杂,但是这个里面会涉及到比较多的知识点。

    手机安装Charles根证书,手机使用Charles的代理,所有请求都经过Charles中间人。
    Charles劫持到请求,替换服务端的证书为自己的伪证书,然后发送给客户端,客户端使用Charles根证书来验证这个伪证书,验证通过得到公钥,然后用公钥加密对话秘钥发送回Charles中间人,Charles中间人私用私钥解密得到对话秘钥并保存,然后再把对话秘钥用服务端的公钥加密返回给服务端,这样就表示两端握手成功,可以进行通信了。而且中间人也获得了之后的对话秘钥,可以解密之后的对话信息

    6、HTTPS

    加密原理

    HTTPS(HTTP Secure) 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和TLS(Transport Layer Security)协议代替而已。通常,HTTP 直接和 TCP 通信。当使用 SSL 时,则演变成先和 SSL 通信,再由 SSL 和 TCP 通信了。简言之,所谓 HTTPS,其实就是身披 SSL 外壳的 HTTP。在采用 SSL 后,HTTP 就拥有了 HTTPS 的加密、证书和完整性保护这些功能。
    SSL 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL 协议使用。可以说 SSL 是当今世界上应用最为广泛的网络安全技术。

    加密和解密同用一个密钥的方式叫做共享密钥加密,也被称为对称密钥加密。
    使用两把密钥的公开密钥加密,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。

    HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。

    如何保证公开密钥加密的公开密钥的真实性?
    首先,服务器的运营人员向数字证书认证机构提供公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。
    服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。公钥证书也可叫做数字证书或直接称为证书。
    接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二,服务器的公开密钥是值得信赖的。

    为什么不一直使用HTTPS

    • 与纯文本通信相比, 加密通信会消耗更多的CPU资源以及内存资源, 如果每次通信都加密, 会消耗相当多的资源, 平摊到一台计算机上时, 能够处理的请求数量必定会随之减少.
    • 节约购买证书的开销也原因之一.

    HTTPS过程

    image.png

    前提:客户端发起链接 三次握手,建立TCP连接
    步骤1:客户端通过发送 Client Hello 报文开始 SSL 通信。报文中包含客户端支持的 SSL 的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
    步骤2:服务器可进行 SSL 通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL 版本以及加密组件。
    步骤3:之后服务器发送 Certificate 报文。报文中包含公开密钥证书。
    步骤4:最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的 SSL 握手协商部分结束。

    ( 客户端从内置的CA根证书对服务器发送来的数字证书进行验签,如果一致,说明证书是CA颁发的。否则提示过期,警告等等)

    步骤5:SSL 第一次握手结束之后,客户端以 Client Key Exchange 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。
    步骤6:接着客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret密钥加密。
    步骤7:客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
    步骤8:服务器同样发送 Change Cipher Spec 报文。
    步骤9:服务器同样发送 Finished 报文。
    步骤10:服务器和客户端的 Finished 报文交换完毕之后,SSL 连接就算建立完毕。当然,通信会受到 SSL 的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。
    步骤11:应用协议通信,即发送 HTTP 响应。
    步骤12:最后由客户端断开连接。断开连接时,发送 close_notify 报文。

    HTTP vs HTTPS
    区别:

    1. http是超文本传输协议,信息是明文传输。https则是具有安全性的ssl加密传输协议
    2. 端口不一样,前者(http)是80,后者(https)是443。
    3. http的连接很简单,是无状态的 。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 ,要比http协议安全
    4. https协议需要到ca申请证书,一般免费证书很少,需要交费
    5. https可以有效的防止运营商劫持,解决了防劫持的一个大问题。

    8、DNS劫持([https://www.jianshu.com/p/b2bbb9afd3e9]、[https://www.jianshu.com/p/e299f3ce4482]、[https://blog.csdn.net/icefishlily/article/details/78863305]

    DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
    
    现在假如我们访问一个网站www.baidu.com从按下回车到百度页面显示到我们的电脑上会经历如下几个步骤:
    1:计算机会向我们的运营商(移动、电信、联通等)发出打开www.baidu.com的请求。
    2:运营商收到请求后会到自己的DNS服务器中找www.baidu.com这个域名所对应的服务器的IP地址(也就是百度的服务器的IP地址),这里比如是115.239.210.27。
    3:运营商用第二步得到的IP地址去找到百度的服务器请求得到数据后返回给我们。
      其中第二步就是我们所说的DNS解析过程
    
    DNS劫持
    由于域名->IP这个过程中,其解析是基于UDP 协议实现,所以报文是明文状态,可能会在请求过程中被监测,然后攻击者做一些自己的处理,比如返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址。根本原因就是以下两点:
    1:恶意攻击,拦截运营商的解析过程,把自己的非法东西嵌入其中。
    2:运营商为了利益或者一些其他的因素,允许一些第三方在自己的链接里打打广告之类的。
    
    防DNS劫持
    根本解决:不走运营商的DNS解析也就不会存在DNS被劫持的问题。
    简而言之:把项目中请求的接口替换成IP,URL是字符串,域名替换IP。
    IP地址来源:
    1、HTTPDNS
    HTTPDNS是客户端基于http协议向服务器A发送域名B解析请求(例如:[www.baidu.com](https://www.baidu.com)),服务器A直接返回域名B对应的ip地址(例如:115.239.210.27),客户端获取到的IP后就向直接往此IP发送业务协议请求。
    这种方式替代了基于DNS协议向运营商LocalDNS发起解析请求,可以从根本上避免LocalDNS造成的域名劫持问题。
    国内提供域名解析 API 接口的,有 DNSPod,现在国内有很多厂商为 DNSPod 开发了 SDK,比如 阿里、七牛(开源)等。
    
    2、内置IP列表
    可以在启动等阶段由服务端下发域名和 IP 的对应列表,客户端来进行缓存,发起网络请求的时候直接根据缓存 IP 来进行业务访问。
    
    具体:
    基于NSURLProtocol可拦截iOS系统上基于上层网络库NSURLConnection/NSURLSession发出的网络请求;
    通过注册自定义NSURLProtocol,用于拦截上层网络请求,并创建新的网络请求接管数据发送、接收、重定向等处理逻辑,将结果反馈给原始请求。
    自定义NSURLProtocol处理过程概述:
    在canInitWithRequest中过滤要需要做HTTPDNS域名解析的请求;
    请求拦截后,做HTTPDNS域名解析;
    解析完成后,同普通请求一样,替换URL.host字段,替换HTTP Header Host域,并接管该请求的数据发送、接收、重定向等处理;
    
    

    9、SPDY & WebSocket 图解HTTP-3

    image.png

    SPDY 没有完全改写 HTTP 协议,而是在 TCP/IP 的应用层与运输层之间通过新加会话层的形式运作。同时,考虑到安全性问题,SPDY 规定通信中使用 SSL。
    SPDY 以会话层的形式加入,控制对数据的流动,但还是采用 HTTP 建立通信连接。

    使用 SPDY 后,HTTP 协议额外获得以下功能。
    多路复用流:通过单一的 TCP 连接,可以无限制处理多个 HTTP 请求。所有请求的处理都在一条 TCP 连接上完成,因此 TCP 的处理效率得到提高。
    赋予请求优先级:SPDY 不仅可以无限制地并发处理请求,还可以给请求逐个分配优先级顺序。这样主要是为了在发送多个请求时,解决因带宽低而导致响应变慢的问题。
    压缩 HTTP 首部:压缩 HTTP 请求和响应的首部。这样一来,通信产生的数据包数量和发送的字节数就更少了
    推送功能:支持服务器主动向客户端推送数据的功能。这样,服务器可直接发送数据,而不必等待客户端的请求。
    服务器提示功能:服务器可以主动提示客户端请求所需的资源。

    WebSocket,即 Web 浏览器与 Web 服务器之间全双工通信标准。
    一旦 Web 服务器与客户端之间建立起 WebSocket 协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可相互发送 JSON、XML、HTML 或图片等任意格式的数据。
    WebSocket 协议的主要特点:

    推送功能:支持由服务器向客户端推送数据的推送功能
    减少通信量:只要建立起 WebSocket 连接,就希望一直保持连接状态。和 HTTP 相比,不但每次连接时的总开销减少,而且由于 WebSocket 的首部信息很小,通信量也相应较少了。
    为了实现 WebSocket 通信,在 HTTP 连接建立之后,需要完成一次 “握手” 的步骤。

    握手·请求
    需要用到 HTTP 的 Upgrade 首部字段,告知服务器通信协议发送改变,已达到握手的目的。(Upgrade: websocket)

    握手·响应
    返回状态码 101 Switching Protocols 的响应


    image.png

    10、HTTP 1.0/1.1/2.0 && QUIC

    HTTP1.0 1.1 2.0的区别
    HTTP2.0新特性

    影响HTTP请求快慢的因素

    带宽:
    如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。

    延迟:
    浏览器阻塞(HOL blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。
    DNS 查询(DNS Lookup):浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。
    建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。

    HTTP1.0和HTTP1.1的一些区别

    HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在:

    1、缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
    2、带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
    3、错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
    4、Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
    5、长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

    HTTP2.0和HTTP1.1的一些区别

    1、二进制传输
    HTTP 2.0中所有加强性能的核心在于此--二进制传输。
    之前的HTTP的版本中,我们传输数据方式--文本传输。
    在HTTP 2.0中引入了新的编码机制,所有传输的数据都会被分隔,并采用二级制格式编码。


    image.png

    2、多路复用
    在 HTTP 2.0 中,有两个非常重要的概念,分别是帧(frame)和流(stream)。
    帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。
    多路复用,就是在一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极大的提高传输性能。


    image.png

    3、Header压缩
    在 HTTP 1.X 中,我们使用文本的形式传输 header,在 header 携带 cookie 的情况下,可能每次都需要重复传输几百到几千的字节。
    在 HTTP 2.0 中,使用了 HPACK 压缩格式对传输的 header 进行编码,减少了 header 的大小。并在两端维护了索引表,用于记录出现过的 header ,后面在传输过程中就可以传输已经记录过的 header 的键名,对端收到数据后就可以通过键名找到对应的值。

    4、服务端push
    在 HTTP 2.0 中,服务端可以在客户端某个请求后,主动推送其他资源。
    可以想象以下情况,某些资源客户端是一定会请求的,这时就可以采取服务端 push 的技术,提前给客户端推送必要的资源,这样就可以相对减少一点延迟时间。当然在浏览器兼容的情况下你也可以使用 prefetch 。

    HTTP2.0的多路复用和HTTP1.X中的长连接复用有什么区别?

    HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
    HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
    HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;
    具体如图:


    image.png

    HTTP 1.1 & 2.0存在的缺陷

    HTTP1.1存在的缺陷

    队头堵塞导致:虽然通过持久性连接得到改善,但是每一个请求的服务端响应依然需要按照顺序排队,如果前面的响应处理较为耗费时间,那么同样非常耗费性能。

    HTTP2.0存在的缺陷

    基于连接的TCP协议,在往返时当其中一个数据包遇到问题,TCP连接需要等待整个包完成重传之后才能继续进行,虽然HTTP2.0通过多个stream,使得逻辑上一个tcp连接上的并行内容,进行多路数据的传输,但涉及到TCP收包是否乱序的问题。

    QUIC

    微软出品的github地址
    腾讯揭秘QUIC的五大特性及外网表现
    QUIC 0-RTT实现简析及一种分布式的0-RTT实现方案

    QUIC :Quick UDP Internet Connections;这是一个谷歌出品的基于 UDP 实现的同为传输层的协议,目标很远大,其最终目的是在web上代替TCP和TLS协议。

    QUIC特点

    1、该协议支持多路复用,虽然 HTTP 2.0 也支持多路复用,但是下层仍是 TCP,因为 TCP 的重传机制,只要一个包丢失就得判断丢失包并且重传,导致发生队头阻塞的问题,但是 UDP 没有这个机制。QUIC 的多路复用,在一条 QUIC 连接上可以发送多个请求 (stream),一个连接上的多个请求(stream)之间是没有依赖的。比如说这个packet丢失,不会影响其他的stream。
    2、实现了自己的加密协议,通过类似 TCP 的 TFO 机制可以实现 0-RTT,当然 TLS 1.3 已经实现了 0-RTT 了
    3、支持重传和纠错机制(向前恢复),在只丢失一个包的情况下不需要重传,使用纠错机制恢复丢失的包。纠错机制:通过异或的方式,算出发出去的数据的异或值并单独发出一个包,服务端在发现有一个包丢失的情况下,通过其他数据包和异或值包算出丢失包。在丢失两个包或以上的情况就使用重传机制,因为算不出来了。

    QUIC优点

    具有SPDY的所有优点;
    0-RTT连接;
    减少丢包;
    前向纠错,减少重传时延;
    自适应拥塞控制,减少重新连接;
    相当于TLS加密。

    QUIC具体描述

    • QUIC主要目标是减少连接延迟,客户端第一次连接服务器时,QUIC只需要1RTT的延迟就可以建立可靠安全的连接,相对于TCP+TLS的1~3次RTT要更加快捷。之后客户端可以在本地缓存加密的认证信息,再次与服务端建立连接时可以实现0RTT的连接建立延迟。

    • 加密认证的报文。QUIC把TLS(1.3)等效加密,几乎每个UDP包都加密,报文body都经过加密,从头到脚几乎无死角,对证书也有一些压缩优化,每一个加密包独立认证。这个特性对直播来说,在客户端的防盗链、盗播、劫持上是有好处

    • 连接迁移。传统NAT遇到的问题,比如小区运营商切换端口,导致设备端判断不了新的连接标识,需要重联。而QUIC使用公共包头和连接ID,可以在网络切换的时候不重连,从室内到室外,在理论上可以做到连接不断网

    • QUIC同时复用了HTTP2.0的多路复用(Multiplexing)功能,但由于QUIC基于UDP,避免了HTTP/2的Head-of-Line Bolcking问题。
      QUIC基于UDP,运行在用户域而不是系统内核(TCP的核心拥塞控制在内核),使得QUIC协议可以快速部署和更新。

    -重传与恢复
    与TCP类似,QUIC每发送一个包后,都会等待回复一个确认包。当丢包率超过协议的纠错阀值,会显示与隐式进行重传。
    对于某些重要的数据包,在确认丢失前就会进行重传。这样在网络中会有若干个相同包同时传输,任何一个成功抵达就完成了连接,通过这样降低丢包率。接收方对于关键数据包的多次发送和普通数据包的超时重传,都采用相同的重复包处理机制。
    QUIC在拥塞避免算法上还加入了心跳机包,用于减少丢包率。
    QUIC改进的拥塞控制。TCP的拥塞控制包含了四个算法:慢启动,拥塞避免,快速重传,快速恢复。QUIC 协议当前默认使用TCP协议的Cubic拥塞控制算法,同时也支持 CubicBytes, Reno, RenoBytes, BBR, PCC 等拥塞控制算法。同时QUIC拥有完善的数据包同步机制,在应用层做了很多网络拥塞控制层面的优化,能有效降低数据丢包率,有助降低复杂网络下的直播卡顿率,提升传输效率,使得推流更流畅。
    QUIC使用前向纠错(FEC)来恢复数据,FEC采用简单的异或方式。每次发送一组数据,即每个数据包除了本身的数据以外,会带有其他数据包的部分数据,在少量丢包的情况下,可以使用其他数据包的冗余数据完成数据组装而无需重传,从而提高数据的传输速度。(这种做法同时也带来了冗余,可能没10个包中就要额外传输1个冗余包,在网络状况好的时候是一种浪费,目前谷歌已经废弃了QUIC的FEC功能)

    -安全性
    QUIC对每个散装的UDP包都进行了加密和认证的保护,并且避免使用前向依赖(如CBC模式)的方法,这样每个UDP包可以独立地根据IV进行加密或者认证处理。
    QUIC使用了两级密钥机制:初始密钥和会话密钥。初次连接时不加密,并协商初始密钥。初始密钥协商完毕后再马上协商会话密钥,这样可以保证密钥的前向安全性,之后通信过程还可以实现密钥的更新。接收方收到密钥更新时,需要用新旧两种密钥对数据进行解密,直到成功才会正式使用新密钥。

    -0RTT握手过程
    QUIC握手过程需要一次数据交互,0RTT即可以完成握手过程的密钥协商,比TLS相比效率提供了5倍。
    QUIC在握手过程使用Diffie-Hellman算法协商初始密钥,初始化密钥依赖于服务器存储的一组配置参数,该参数会周期性更新。初始密钥协商成果后,服务端会提供一个临时随机数,双方根据这个随机数再生成会话密钥。
    client具体握手过程如下:

    相关文章

      网友评论

          本文标题:iOS 网络相关

          本文链接:https://www.haomeiwen.com/subject/csoightx.html