OSI七层模型

应用层:为计算机用户提供服务
表示层:数据处理(编解码、加密解密、压缩解压)
会话层:管理(建立、维护、重连)应用程序间的会话
传输层:为两台主机间的通信提供数据传输服务
网络层:路由和寻址
数据链路层:帧编码和误差纠正控制
物理层:透明的传送比特流运输

TCP/IP四层模型

常见网络协议
应用层 HTTP,DNS,SSH…
传输层 TCP,UDP
网络层 IP,NAT,RIP,APR…
网络接口层 MAC,CSMA/CD…

Http

HTTP和HTTPS的区别

  • 端口号:HTTP默认为80,HTTPS默认为443。
  • URL前缀:HTTP为http://,HTTPS为https://
  • 安全性:HTTP协议以明文方式传递信息,不提供任何加密,而HTTPS在HTTP基础上加了SSL/TLS协议,为浏览器和服务器之间的通信加密。在进行数据传输之前,对数据进行加密,再发到服务器。
  • 网站申请流程:HTTPS协议需要额外申请证书,一般需要交费,Web服务器启动SSL需要获得一个服务器证书并将该证书与要使用SSL的服务器绑定。
  • 搜索优先级:百度和谷歌两大搜索引擎都已经明确表示HTTPS网站将会作为搜索排名的一个重要权重指标。

HTTP如何保存用户状态

HTTP协议是无状态的,这意味着浏览器并不知道是张三还是李四在和服务端打交道,这时就需要Cookie和Session配合:
用户第一次请求服务器后,服务器将用户信息保存在对应的Session,请求返回时将SessionID返回给浏览器,浏览器将SessionID附加给Cookie,同时记录此SessionID属于哪个域名。
用户第二次访问服务器时,就通过Cookie中附加的SessionID来判断用户是否存在。
综上:SessionID是连接Cookie和Session的一座桥梁。

Cookie和Session的区别

  • 作用范围:Cookie 保存在客户端(浏览器),Session 保存在服务器端。
  • 存取方式:Cookie 只能保存 ASCII,Session 可以存任意数据类型。
  • 有效期:Cookie 可设置为长时间保持,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • 隐私策略:Cookie 存储在客户端,比较容易遭到不法获取,Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小:单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

HTTP基于TCP还是UDP

HTTP/3.0之前基于TCP,而HTTP/3.0将弃用TCP,改用基于UDP的QUIC协议。

TCP/UDP

TCP和UDP均属于OSI七层模型中的传输层。

TCP与UDP的区别

  • 是否面向连接:TCP在传输前必须建立连接,传输后要释放连接;而UDP在传输数据之前不需要建立连接。
  • 是否可靠传输:TCP在传输之前会有三次握手建立连接,在数据传输时,有确认、失败重传、拥塞控制等机制,且在传输完成后有四次挥手断开连接,保证数据无差别、不丢失、不重复、按序到达;而远端主机收到UDP报文后不需要做出任何确认,并且不保证数据完整性和是否按序到达。
  • 是否有状态:TCP会记录自己发送消息的状态比如是否发送了、是否被接收了等;而UDP无服务状态,只管发出去即可。
  • 传输效率:由于TCP进行传输时多了连接、确认、重传等机制,效率远低于UDP。
  • 传输形式:TCP面向字节流;UDP面向报文。
  • 首部开销:TCP(20-60字节);UDP(8字节)。
  • 是否提供广播或多播服务:TCP只支持点对点通信;UDP支持一对一、一对多、多对一、多对多。

综上:

TCP UDP
是否面向连接 ×
是否可靠 ×
是否有状态 ×
传输效率
传输形式 字节流 报文
首部开销 20-60bytes 8bytes
广播/多播 ×

使用场景

  • TCP:用于对传输准确性要求非常高的场景,例如QQ和微信的文件传输。
  • UDP:用于即时通讯,对数据传输的效率有较高要求,比如语音、视频等。

TCP的三握四挥

三次握手

  • 一次握手:客户端发送SYN(SEQ = X) ->服务器
  • 二次握手:服务端发送SYN + ACK(SEQ = y, ACK = X + 1) ->客户端
  • 三次握手:客户端发送ACK(ACK = y + 1) ->服务器,建立连接

为什么三次握手

  1. 第一次:客户端什么都不能确认,服务器确认对方发送正常,自己接收正常。
  2. 第二次:客户端确认自己发送、接收正常,对方发送、接收正常;服务器确认对方发送正常、自己接收正常。
  3. 第三次:客户端和服务器都确认正常。

为什么不是两次或四次握手?
如果使用两次握手,在第一次握手时,客户端发送SYN数据包,服务器收到后没有发送确认报文,客户端超时后重新发送SYN数据包,此时如果网络中存在重传机制,客户端可能会接收到旧的SYN数据包,导致连接建立错误。 而三次握手可以避免这种情况的发生。

既然三次握手已经建立连接,就没有必要再进行第四次握手。

四次挥手

  • 一次挥手:客户端发送一个FIN(SEQ = X) ->服务器,用来关闭客户端到服务器端的数据传送。
  • 二次挥手:服务器收到FIN, 发送一个ACK(ACK = X + 1) ->客户端。
  • 三次挥手:服务器关闭与客户端连接并发送一个FIN(SEQ = Y) ->客户端请求关闭连接。
  • 四次挥手:客户端发送一个ACK(ACK = Y + 1) ->服务器,服务器正式关闭。此时,如果客户端在2MSL后依然未收到回复,代表服务器已正常关闭,客户端就可以关闭。

为什么四次挥手

不像建立连接的过程,接收方收到连接请求后可以立即发送SYN进行连接,释放资源时,接受方在收到发送方的释放连接请求后,还需要一段时间来处理未完成的发送请求,这里需要两次确认发送方的请求:第一次是未处理完,我还不能释放,但是收到了你的请求,告诉发送方一声,等等我;第二次确认表示已经处理完请求了,我也可以进行释放了。

为什么不能把服务器发送的 ACK 和 FIN 合并起来,变成三次挥手?
上面也解释过了,服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,代表我已经收到断开连接的请求。等到数据发完再发FIN。