多级小火箭(TCP/IP原理解析,还有HTTP)
就像火箭一样,为了把物资送到目的地,有一节一节的推进器;每一节都有它的使命,完成使命后就变得不重要了。
先介绍一下这个火箭
第一级推进器IP头:
目的是把物资送到目的地,
IP头储存IP地址,到底是怎么寻址的?
先发到IP路由,再转发到服务器。(就像一个巨大的路由器,管理公网的信息转发)
你的计算机不会知道ip地址在哪个计算机上,只有分发ip的Internet权力机构(InterNIC)才知道。所以要根据ip寻找主机就需要先问IP路由。
IP网络中的路由选择是由路由设备完成的。路由器通过执行一定的路由协议,为IP数据报寻找一条到达目的主机或网络的最佳路由,并转发该数据报,实现路由选择。
已经建立连接后还需要通过IP路由吗?我猜是不要,不然为什么同一个路由器下QQ传输会那么快。
第二级推进器TCP头
Transmission Control Protocol传输控制协议
维持数据包的顺序,因为TCP是分段发送的,一段TCP一般默认是536字节;出发的时候是按顺序的,但是在路上有的快一点有的慢一点,最终到达目的地还是需要重新根据TCP头来排序。
最里面一级HTTP
也可能是RPC私人定制和模板货(RPC和Http的区别)
分三个部分:起始行,头部块headers,主体body
起始行就是200,404那些东西。
request:请求头,是浏览器的信息,发送给服务器。
response:响应头,是服务器的信息,发送给浏览器。
这两个的内容要都对的上,也就是请求头里的类型,响应头里要包含。对不上浏览器就打不开。
主体就是具体要传递的信息。
再来说说发射流程
三次握手
打招呼,回应,建立连接。
为什么一定要三次?第2次防止服务器已经死掉,第3次防止客户端死掉的失效连接(加时间戳不就好了?)。
四次挥手
A:我要挂了你还有什么要说的(不再发送消息,可以接收),B:好的(直接挂或者把剩下的消息发完再挂),B:我准备好挂了,A:我开始准备挂(等一下2MSL(Maximum Segment Lifetime报文最大存活时间)时间,没回应,挂掉)
为什么要等两个报文最大存活时间?
1.怕对面没收到第4次挥手,等待对面回应
2.客户端需要时间释放资源。没释放完又重新连接同一个服务器,新老报文会冲突。
为什么要等2个报文时间,一个不够释放吗?
是保守时间,保证释放资源。
丢包(打网游经常听到的一个词)
啥是丢包?上面的图就很明显的说明了TCP就是一段一段传输的,丢的就是某一段TCP。
丢包的情况一直没收到ACK,可能是ACK丢失也可能根本没发出去;
不过放心,有超时重发机制。
发包的时候起个计时器,过时没有收到ACK确认码,就要重发。计时器随着重发次数翻倍(6s,12s,24s...)。不是无限次的。
ACK (Acknowledge character)即是确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符;表示发来的数据已确认接收无误。
影响TCP性能的地方
TCP缺陷:服务器端没有收到IP的回应,会重试3~5次并且等待一个SYN Time(—般为30秒至2分钟),如果超时则丢弃这个连接。如果受大量无效连接就会消耗很多资源。
HTTP 事务的时延有以下几种主要原因:
(1) 通过 DNS 解析系统将 URI 中的主机名转换成一个 IP地址要花费对应的时间(第一次长,后面直接从缓存取)
(2) 每条新的 TCP 连接都会有连接建立时延,但如果有数百个 HTTP 事务的话, 这个时间消耗值会快速地叠加上去。(3次握手耗费资源)
(3) 网络传输请求报文及服务器处理请求报文都需要时间。
(4) Web 服务器会回送 HTTP 响应的花费时间。
延迟确认机制(ACK)
由于确认报文很小, 所以 TCP 允许在发往相同方向的输出数据分组中对其进行“捎带”。 TCP 将返回的确认信息与输出的数据分组结合在一起, 可以更有效地利用网络。等100-200ms看有没有顺风车。
Nagle算法与TCP_NODELAY(与延迟确认机制对应)
Nagle 算法鼓励发送全尺寸的数据段,避免网络中充斥着许多小数据块。
和延迟确认很像,装满再发车,等100-200ms;好处是省资源,坏处就是装不满就白等了。
HTTP 应用程序常常会在自己的栈中设置参数 TCP_NODELAY, 禁用Nagle 算法,提高性能。(Tomcat通过server.xml进行设置,默认为true)默认都是禁用的。
TCP慢启动
刚开始传输的时候怕网络堵塞,先发少量的信息测试,再逐渐增加。(所以下载东西的时候开始都是几KB也是这个原因?)
HTTP各个版本
HTTP1.1(最经典的)
使用时间最长的一个,现在还有很多占有量。
短连接
http1.0默认是短连接,建立一个连接,任务完成就结束;比如获取一个图片。
并行比串行效率大大提高(看上去)
每次都要握手挥手,延迟发送延迟确认,串行的话这些时间都要累加起来;但是并行资源消耗大,每个浏览器在不同的Http协议版本中都限制了并行数量,Chrome是6个(有点太少了?这是对每个域名的并行数量,不是一个浏览器的并行数量)。
持久连接(长连接),效率更高
Connection: Keep-Alive;http1.1以后的版本默认打开;在持久连接中所有请求都是串行的;连接需要3次握手,断开需要4次挥手,所以一直连着还是很有意义的;当然不是永久连接,服务器可以设置这个时间。
管道化持久连接,更快
并行的持久连接。
对管道化连接有几条限制:
必须按照与请求相同的顺序回送 HTTP 响应
HTTP 客户端必须做好连接会在任意时刻关闭的准备,重新发出这些请求。
由于出错了会重试的机制,只有幂等的请求能够被管线化;由于无法安全地重试 POST 这样的非幂等请求, 所以出错时, 就存在某些方法永远不会被执行的风险。(所以查询用GET更快)
浏览器有并行限制,怎么开更多的连接提高效率?
使用虚拟域名,每个域名开6个。(http/2就不用考虑这个问题了)
HTTP/2(太空电梯)
如果1.1是火箭,那2.0就是太空电梯了,它通过一个双向数据流来传递数据。
HTTP 2.0 所有的通信都在一个连接(TCP连接)上完成,这个连接可以承载任意数量的双向数据流(那不就是websocket?)。
大多数HTTP 连接的时间都很短,而且是突发性的,HTTP 2.0 通过让所有数据流共用同一个连接,可以更有效地使用TCP 连接,让高带宽也能真正的服务于HTTP的性能提升。
HTTP/2和websocket
http/2无法做到websocket那样实时通信,但是网上也有各种说法,让子弹再飞一会吧。
单连接多资源方式的好处:
1.可以减少服务连接压力,内存占用少了,连接吞吐量大了
2.由于 TCP 连接减少而使网络拥塞状况得以改观;
3.慢启动时间减少,拥塞和丢包恢复速度更快。
二进制分帧(frame)
用二进制代替明文传输(二进制比明文效率高);
由于只有一个连接,来自不同数据流的帧可以交错发送;帧头就很重要,数据可以乱序,再根据每个帧首部的流标识符重新组装。
有点像TCP头的作用。
多路复用(Multiplexing)
解决了之前并行连接数上限的问题。
http2连接可以承载数十或数百个流的复用,多路复用意味着来自很多流的数据包能够混合在一起通过同样连接传输。当到达终点时,再根据不同帧首部的流标识符重新连接将不同的数据流进行组装。
头部压缩(HPACK)
头部信息其实很多都是重复的,不光头部,body也可以压缩。
HPACK,这是一种新的压缩方法,它消除了多余的header 字段;常用的gzip等是报文内容(body)的压缩
使用静态表,然后传id。使用动态表,加入临时的新信息。
服务器推送(Server Push)
服务器可以对一个客户端请求发送多个响应,服务器向客户端推送资源无需客户端明确地请求。
所以怎么确定服务器推过来的就是我需要的?
这是两种写法; 关键字preload修饰这个资源,as表明了资源的文件类型。
服务器推送还有一个很大的优势:可以缓存!也让在遵循同源的情况下,不同页面之间可以共享缓存资源成为可能。
1、推送遵循同源策略;
2、这种服务端的推送是基于客户端的请求响应来确定的。
感觉http/2是在网速大幅提升,4G普及后弄出来的方案,如果是拨号上网的年代,一直连接要花多少网费啊。
HTTP3.0抛弃TCP
大人时代变了,UDP要挑大梁了(并不是)
江湖传闻UDP不安全但是快。
一般用到UDP的地方,网络视频,语音。
UDP是一个无状态的传输协议,容易丢包也不会重传。
QUIC协议特性,全称是Quick UDP Internet Connections。
基于UDP的新协议,但是QUIC在UDP的基础上做了些改造,使得他提供了和TCP类似的可靠性。它提供了数据包重传、拥塞控制、调整传输节奏以及其他一些TCP中存在的特性。又回到TCP了,也就是在UDP的基础上又造了一个TCP,一个符合现在网络特性的新TCP。
HTTP/2的性能瓶颈就是TCP协议
比如3次握手变成初始握手和重复握手:
QUIC在握手过程中使用Diffie-Hellman算法协商初始密钥,初始密钥依赖于服务器存储的一组配置参数,该参数会周期性的更新。初始密钥协商成功后,服务器会提供一个临时随机数,双方根据这个数再生成会话密钥。客户端和服务器会使用新生的的密钥进行数据加解密。
当初有个想法,3次握手的关键就是避免那种无主的幽灵消息,但是只要证明消息是刚发出来的就好了,所以我以为加个时间戳就够了。
实际上要复杂的多,简单的说一说;
客户端去访问服务端,服务端说不行,我们这是内部聚会;然后发给客户端一套制服(长期公钥和其他的一些东西),叫他穿好了再来。
客户端回去后拿着自己家乡的特色产品(短期密钥)和制服组合出来一套新的服饰(初始密钥);他会把特色产品告诉服务端,这样服务端也知道他的新服饰(初始密钥)长什么样了,然后他就直接进去了;只花了一个来回。
之后客户端再想去服务端,只要穿着他的新服饰就可以直接进去了;直到服务端换主题(长期公钥)。
在长期公钥这个时间段可以直接连接,超时了就需要两次握手;
有一个想法,在快超时的时候如果客户端正好还在访问,服务器就把下一个公钥推给客户端,是不是就可以一直实现直接连接了。
多路复用
依靠UDP的机制,比HTTP/2更好的解决了队头阻塞的问题。
连接迁移
这个就厉害了,
QUIC协议使用流ID取代IP和端口,这样就能实现连接迁移。例如说从4G信号切换到wifi,下层的IP和端口变了,但是由于QUIC的流ID没有变,这个连接不会变,可以继续使用这个连接。
IP都变了还能继续连接,这个很诡异啊,怎么实现的呢?
//todo
HTTPS
SSL/TLS目前用的是TLS,SSL用了很久,是上一代加密技术了。
TLS全称传输层安全协议Transport Layer Security Protocol,TLS/SSL是一种加密通道的规范。
数据加密
加密密钥是在握手的时候才确定的。
非对称加密安全,对称加密效率高。
Https的数据加密:非对称加密协商出对称加密的密钥,然后通过对称加密来加密数据,这样提高效率
校验(防篡改)
在信息中增加数字签名(消息摘要在用私钥加密生成数字签名)
1.使用hash算法(md5或其他摘要算法)加密原文生成消息摘要,使用私钥加密消息摘要和原文;
2.用公钥解密信息拿到消息摘要和原文;
3.传过来的原文使用相同的hash算法生成消息摘要;
4.将两个消息摘要对比,判断原文有没有被篡改。
破解数据需要:公钥
篡改数据需要:公钥,私钥,hash算法。
数字证书(身份验证)
通过权威机构颁发,CA是负责签发证书、认证证书、管理已颁发证书的机关。
如何判断证书真伪?
CA把自己的CA证书集成在了浏览器和操作系统里面。(所以要装正版系统啊)
证书有哪些内容?
证书中包含:组织信息、域名信息、公钥、证书有效期等信息。
私钥在哪?
还在CA机构那里;需要CA用私钥进行签名。(所以连接还要去访问CA机构的服务器,不过那是服务端端事了)
CA是国外的,网卡怎么办?
有很多机构都可以进行CA认证,需要得到CA的授权。
其他
socket(套接字)编程:以流的形式在两个socket端传递,服务器和客户端就是两个socket