面试点之《HTTP协议与TCP/IP协议》

362 阅读11分钟

  写本文的目的只是希望更总结简化繁杂的知识点,用更通俗易懂,简明扼要的方式来陈述主要问题,如果要深挖还是需要更专业的资料和书籍。

HTTP协议

HTTP协议全称是超文本传输协议,是一个请求-响应的应用层协议,默认端口号是80。

  • 特点:

    • 传输速度快:传输时只需要传说请求方式和请求路径,由于协议简单,HTTP的服务器规模小,传输速度就比较快;
    • 无状态对于信息上下文没有记忆的能力,每次请求都是独立无关的不保存状态信息,所以为了验证身份等信息引进了cookie、token等方法;
    • 无连接处理完一次请求以后就会断开连接,好处是在某些简单场景下可以节省资源,但是缺点也很明显,需要长连接传输信息时需要频繁的建立连接来传输数据,反而影响了传输速度还浪费了大量资源;
    • 传输类型无限制可以传输任何类型的数据
  • 缺点:
    • 明文传输:报文头部不是二进制传输而是明文传输的

HTTP1.0、HTTP1.1、HTTP2的特性

  • HTTP1.0

    B240BBCC-594E-469E-9A88-6031FF870CC9.png

  • HTTP1.1

    296BEB03-F76B-4566-80A5-0A0608189C15.png

    • 特性:

      • 长连接(Connection:keep-alive):建立起一次连接以后,可以进行多次HTTP请求和响应,问题就在于请求是串行的,会产生队头堵塞;
      • 管线化(pipeliNing):管线化技术是将多个HTTP请求放在一个TCP连接中,而在发送端不需要先等待响应。管线化有几个特点:
        • 新建大量TCP连接开销巨大,且 Chrome浏览器默认最大TCP连接数量是6个,并不能解决延时问题;TCP连接还存在慢启动的问题,即数据发送速度有一个由慢到最快速度的过程,然而慢启动也是为了防止阻塞;
        • 管线化是建立在长连接的基础上的技术,而且客户端和服务端都需要支持管线化,但是并不需要服务端也进行管线化处理,只需要对于管线化处理过的请求接受不失败即可;
        • 由于管线化的种种问题,浏览器一般默认关闭管线化;
        image.png
    • 缺陷:

      • 队头阻塞:如上图所示,下一次请求需要上一次的响应返回之后才能发出,一旦上个请求出现了问题,后面所有的请求都会卡住无法进行;
      • 头部冗余:响应和请求中分为三个部分,状态行、响应/请求、内容。内容主体往往是经过诸如gzip之类的压缩或者本来就是二进制传输的文件。但是 状态行和请求/响应的头部是纯文本传输的
      • 服务端不能主动推送消息
  • HTTP2

    :一个TCP连接上是双向流,流上会有一个或多个消息,而一个TCP连接上可以有多个流;
    消息:一个完整的HTTP请求/响应由一个或多个帧组成。特定消息的帧在同一个流上发送,这意味着一个HTTP请求/响应只能在一个流上传递;
    帧数信息传递的最小单位

    • 特性:
      • 二进制传输:HTTP2性能提升的核心就是采用了二进制分帧层协议用二进制传输数据,而不像HTTP1.0采用文本传输;
      • 多路复用:HTTP2只需要建立一个连接,一个连接上可以有多个流,消息被切割成多个帧在流上传输,每个请求会带上编号,传输到服务端以后再根据编号进行重组,除非超出服务端接收限制否则不会堵塞;
      • 头部压缩:采用HPACK格式来压缩首部,需要服务端和客户端之间维护:
        • 一份拥有61个值的静态字典,包含常见的头部名称、头部名称和值的组合;
        • 一份可以动态添加内容的动态字典;
        • 可以对传输的首部进行编码的哈夫曼编码
      • 服务端可以主动推送消息

  需要注意的是,HTTP2的请求报文的字段都是小写。

HTTPS

简单来说:HTTP+SSL/TLS=HTTPS,HTTPS协议就是在HTTP协议的基础上增加了SSL/TLS(TLS是SSL的加强版协议)。默认端口443。在HTTPS中使用到了三种加密方式,哈希算法对称加密非对称加密

三种加密方式

  • 对称加密:使用同一个密钥进行加密和解密

    • 优点:解码速度快,传递信息效率高;
    • 缺点:安全性低,任一一方密钥被盗取都会导致安全失效。
  • 非对称加密:公钥加密,私钥解密

    • 优点:
      • 不需要发送私钥,安全性更高;
      • 信息传输一对多,公钥是公开的,Server保留一份私钥即可和多个Client进行加密传输;
    • 缺点:
      • 解密效率低,消耗资源多
      • 公钥中不包含身份信息,存在中间人攻击的可能

  虽然经常说,公钥和私钥可以互相加密解密,但是严格来讲,私钥并不能拿来加密,仅仅是作为数字签名使用,这是由于密码学中生成公钥私钥时对不同变量的数学要求是不同的,因此公钥私钥抵抗攻击的能力也不同,在实际使用中不可互换

  • 哈希算法(散列函数)

  最大的特点是不可逆,一个哈希值对应着多个明文,无法进行反编译。这样可以保证要加密为数字签名的信息摘要无法被篡改伪造。

优势

  • 对明文传输进行加密(对称加密)

  为什么明文传输使用对称加密这种安全性较低的加密,主要因为非对称加密解密的速度慢资源消耗多,影响信息交流的效率。在能确定身份的情况下,使用对称加密信息交流的效率高。

  • 对身份和信息完整性的验证(哈希算法+非对称加密)

  如果没有证书进行身份验证,就有可能存在中间人攻击,ServerClient原本打算使用公钥A和私钥A进行验证时,被中间人C攻击,C使用公钥A和Client进行信息传递,然后使用他自己生成的私钥B和公钥B和Server进行信息传递。 image.png   问题的核心在于,Client无法确定这个公钥是不是Server发出的。而CA证书里包含了Server的数字签名和明文信息,可以确定发送方的身份。

  数字签名能解决两个问题,一个是验证用户的身份,二是验证报文的完整性,防止信息被篡改

  拿到CA证书后会获得一个明文还有数字签名,使用CA证书的公钥去解密数字签名得到一个信息摘要A,然后把明文使用哈希算法处理得到信息摘要B,把信息摘要A和信息摘要B相比较,如果相同就说明信息没有被篡改。

  Server把信息使用哈希算法处理后得到信息摘要A再使用私钥A加密成数字签名,传递给Client之后,Client使用公钥解密得到信息摘要A,把原本获得的信息也进行哈希算法处理得到信息摘要B,如果信息摘要A==信息摘要B,那么说明没有被篡改。

image.png

TCP/IP协议

三次握手

  1. 客户端发送SYN请求同步报文(SYN=1),并指明客户端初始化序列号seq=x
  2. 服务器接收到报文并回复ACK确认报文(ACK=1)SYN请求同步报文(SYN=1),确认号是对方的初始化序列号+1即ack=x+1,初始化序列号seq=y;
  3. 客户端发送ACK确认报文(ACK=1),确认号是对方的初始化序列号+1即是ack=y+1。序列号由于自己是第二次发送,所以是初始化序列号基础上+1即seq=x+1

屏幕快照 2019-05-15 下午4.41.02.png

  • 字段解释:

    • seq:32位的同步序号,发起方用来标识发送的字节流,动态生成且随时间变化每4ms加1;
    • ack:32位的确认序号,ACK=1时才有效;
    • ACK:请求确认报文;
    • SYN:请求同步报文;
    • RST:重置连接
  • 为什么是三次握手

  TCP协议是全双工通信,需要互相确认客户端和服务端的发送和接收能力是否正常,最少需要三次握手

  假设一下,当两次握手时就建立起了连接,而第二次握手客户端并没有接收到,服务端已经建立起了链接。此时客户端再重发一次又建立了一次连接,但是第一次连接并无信息发送,白白浪费了资源。

image.png

  • 三次握手中能否携带数据

  第一次不能携带数据,假如第一次就可以携带,攻击者传输大量报文给服务端,服务端需要接收这些报文会消耗大量内存。这样也是防止服务端被攻击。

  第二次也不能携带数据,因为此时服务端并不能确定客户端有接收能力(可参考上图第二次握手时服务端可以确定的状态)。

  第三次可以携带数据

  • 其中一次握手时数据丢失怎么办

  第一次握手和第二次握手丢失时,由于客户端没有接收到确认信息,所以都会由客户端重新发送第一次握手

  第三次握手丢失时,是由服务端重新发送第二次握手(SYN攻击就在此时),当一方发出一个报文后,会开启重传计时器,等到接收到ACK确认报文后计时器停止。当超过一个设定的时间后还没有接收到确认报文就会重传。默认情况下,Windows主机默认重传5次。大多数Linux系统默认最大15次。两种操作系统都可配置。如果次数达到限制以后还没接受到确认信息,服务端会发送一个RST报文重置所有报文信息进入CLOSE状态,需要从第一次握手重新开始。

  • SYN攻击

  服务端资源在第二次握手分配,客户端在第三次,假如有人故意伪造大量虚假IP进行请求,在第二次握手之后,不进行第三次握手,服务端就会不停的重发第二次握手确认,这样会导致大量资源被消耗甚至卡死宕机。

  如果在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。

四次挥手

  1. 客户端发送FIN报文,关闭TCP连接,停止发送数据;(FIN=1,seq=u)
  2. 服务端接收到FIN报文后会先发送一个ACK确认报文;(ACK=1,ack=u+1,seq=v)
  3. 服务端传递完所有信息后发送FIN报文表明自己准备关闭连接;(FIN=1,ACK=1,ack=u+1,seq=w)
  4. 客户端发送ACK确认报文表明自己接收到了服务端发送的报文。(ACK=1,ack=w+1,seq=u+1)

从下图可以看出,服务端关闭的要比客户端早

image.png

  • 字段解释:

    • FIN:释放连接报文
  • 为什么是四次挥手

  这是因为TCP的半关闭状态导致的,此时是指:客户端关闭了但是服务端还可以进行信息传输。可以注意的是,在服务端的第二次和第三次挥手是分开的而不是像握手一样合并为了一次,这是因为在服务端发送ACK确认报文之后,服务端知道客户端没有信息要发送了,但是服务端可能还有未发送完的数据,所以需要客服端数据发送完之后再进行第三次挥手发送FIN关闭报文

  • 四次挥手时等待2MSL的意义是什么

  因为数据包在网络中的生命周期是一个MSL(报文最大生命周期),在通信中发送包和接收包一来一回就是2MSL,超过2MSL后,数据包就不可能存在,所以可以确保不会再收到消息了。

特别感谢