那些@#*¥……&*http/Tcp的事儿

Chapter of HTTP

https

https对比http?
http传输信息是明文,这个信息有可能被某个中间人恶意截获甚至篡改, 不够安全

直接使用对称加密的问题?解决方法?
第一次约定加密方式和密钥的通信仍然是明文,如果第一次通信就已经被拦截了,那么密钥就会泄露给中间人,中间人仍然可以解密后续所有的通信内容。
用非对称加密,为密钥的传输做一层额外的保护。非对称加密的一组秘钥对中,包含一个公钥和一个私钥。明文既可以用公钥加密,用私钥解密;也可以用私钥加密,用公钥解密。

核心:加密了密钥传输的过程
原理:服务端使用非对称加密获得两方通信密钥
过程:服务端有一套公钥私钥,将公钥key1发送给客户端,客户端将两方通信密钥key2用key1加密后发送给服务端,服务端再用公钥key1对应的私钥去机密,获得key2。
问题: 这个过程中key1可能被第三方拦截,第三方有自己的一套公钥私钥,将key1替换成第三方的key3,再传递给客户端,
客户端用key3加密key2,然后又被第三方拦截,第三方用自己key3对应的私钥解密获得key2, 然后又用key3加密key2发送给服务端,
客户端服务端仍然像正常过程用key2加密解密通信内容,但第三方已经拿到key2, 可以窃听到通信内容。
解决方案:引入第三方证书
过程:服务端不再直接发送公钥key1, 而是发送证书,客户端验证证书真伪后解密获得公钥key1。

详细过程:

  1. 客户端发送client hello,包括一个随机数和协议和加密方式
  2. 服务端向客户端发起server hello, 包括一个随机数和服务端筛选后的协议和加密方式和证书。
  3. 客户端校验证书。证书中包含了服务端公钥,证书签名。证书签名是被证书私钥加密的,客户端有证书公钥,客户端用证书共钥揭秘签名得到摘要1,使用认证机构同样的摘要算法对证书源文件计算得到摘要2,对比摘要1和摘要2,相同说明证书可靠,取出服务端公钥。
    客户端生成一个随机数,通过服务端公钥加密发送给服务端。这个也是HTTPS中唯一的一次非对称加密。
  4. 服务端用自己的私钥揭秘被自己公钥加密过的客户端随机数,这样客户端。服务端就都有了3个随机数。用之前约定的加密方式双方都能生成通信密钥。
  5. 双方都要进行一次加密验证,看下这个加密算法能否正常使用。
  6. 最后一步,它们就可以开始使用HTTPS进行加密通信了.

在 TLS 握手阶段,两端使用非对称加密的方式来通信,但是因为非对称加密损耗的性能比对称加密大,所以在正式传输数据时,两端使用对称加密的方式通信。

第三方能伪造证书吗?
不能,证书的签名是由服务端网址等信息生成的,并且经过机构私钥加密,中间人无法篡改。

参考 漫画:什么是 HTTPS 协议?


http发展史及版本对比

版本 连接特点 请求特点
http 1.0 连接不复用
http 1.1 连接复用 请求是 串行
持久化连接 不能顺次发多个请求
管线化 可以顺次发多个请求
http2 多路复用,解决 队头阻塞问题 请求是 并行


http2 vs http1.x
效率高:

  • 多路复用
    多路复用代替了HTTP1.x的序列和阻塞机制
    在HTTP1.x中,如果想并发多个请求,必须使用多个 TCP 链接,且浏览器为了控制资源,还会对单个域名有 6-8个的TCP链接请求限制
    HTTP2中:
    同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接而带来的延时和内存消耗。
    单个连接上可以并行交错的请求和响应,之间互不干扰
  • 二进制协议(信息解析更快)
  • 头部压缩
  • 服务端推送



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

参考 HTTP2.0,HTTP1.1,HTTP1.0三者在通性性能上的优化方法



?? 当我们在说队头阻塞,我们在说什么

pipelining在接收response返回时,也必须依顺序接收,如果前一个请求遇到了阻塞,后面的请求即使已经处理完毕了,仍然需要等待阻塞的请求处理完毕。这种情况就如图中第三种,第一个请求阻塞后,后面的请求都需要等待,这也就是队头阻塞(Head of line blocking)。
为了解决上述阻塞问题,http2中提出了多路复用(Multiplexing)技术,Multiplexing是通信和计算机网络领域的专业名词。http2中将多个请求复用同一个tcp链接中,将一个TCP连接分为若干个流(Stream),每个流中可以传输若干消息(Message),每个消息由若干最小的二进制帧(Frame)组成。也就是将每个request-response拆分为了细小的二进制帧Frame,这样即使一个请求被阻塞了,也不会影响其他请求,如图中第四种情况所示。

参考 http中的队头阻塞(Head of line blocking)多路复用(Multiplexing)


状态码和报文

301 vs 302 区别
301永久重定向,302临时重定向
301:
旧地址A的资源已经被永久地移除了(这个资源不可访问了),
搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址
301比较常用的场景是使用 域名跳转。比如,我们访问 http://www.baidu.com 会跳转到 https://www.baidu.com

302:302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。
比如未登陆的用户访问用户中心重定向到登录页面。

使用301跳转的场景:
1)域名到期不想续费(或者发现了更适合网站的域名),想换个域名。
2)在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。
3)空间服务器不稳定,换空间的时候。

使用302跳转的场景:
–尽量使用301跳转!—网址劫持!
从网站A(网站比较烂)上做了一个302跳转到网站B(搜索排名很靠前),这时候有时搜索引擎会使用网站B的内容,但却收录了网站A的地址,这样在不知不觉间,网站B在为网站A作贡献,网站A的排名就靠前了。


Chapter of TCP

TCP vs UDP?

应用层 HTTP/FTP/DNS
SSL
传输层 TCP/UDP
网络层 IP/APR
链路层

UDP

  1. 不用建立连接
  2. 不会对数据报文进行任何拆分和拼接操作
  3. 不保证有序且不丢失的传递到对端
  4. 没有任何控制流量的算法
    不可靠,但是简单高效,适用于实时性要求高场景

TCP 基本是和 UDP 反着来,建立连接断开连接都需要先需要进行握手。在传输数据的过程中,通过各种算法保证数据的可靠性,当然带来的问题就是相比 UDP 来说不那么的高效。

TCP连接断开的握手

连接三次握手

a.客户端发送SYN给服务端
b.服务端收到后发送ACK+SYN给客户端
c.客户端发送ACK给服务端,完成连接

?? 思考: 为啥需要三次连接
为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误

一端(client)A发出去的第一个连接请求报文并没有丢失,而是因为某些未知的原因在某个网络节点上发生滞留,导致延迟到连接释放以后的某个时间才到达另一端(server)B。本来这是一个早已失效的报文段,但是B收到此失效的报文之后,会误认为是A再次发出的一个新的连接请求,于是B端就向A又发出确认报文,表示同意建立连接。如果不采用“三次握手”,那么只要B端发出确认报文就会认为新的连接已经建立了,但是A端并没有发出建立连接的请求,因此不会去向B端发送数据,B端没有收到数据就会一直等待,这样B端就会白白浪费掉很多资源。如果采用“三次握手”的话就不会出现这种情况,B端收到一个过时失效的报文段之后,向A端发出确认,此时A并没有要求建立连接,所以就不会向B端发送确认,这个时候B端也能够知道连接没有建立。

断开四次握手

服务端和客户端都要发送ACK和FIN
a.A-B发送FIN
b.B-A 发送ACK
c.B-A 发送FIN
d.A-B发送ACK

?? 思考,为什么连接3次,断开4次
本质的原因是tcp是全双公的,要实现可靠的连接关闭,一方发出结束报文,另一方还可以继续发送数据,得双方都发送了结束报文FIN和应答ACK。

为什么上图中的A在TIME-WAIT状态必须等待2MSL时间呢?
第一,为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。
第二,A在发送完ACK报文段后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。