TCP、UDP、HTTP

432 阅读12分钟

UDP、TCP

UDP

无连接、高效

UDP不需要传递数据之前,三次握手,想发就发了。也不会对报文做任何拆分、拼接操作

  • 发动端:应用层将数据发给UDP,UDP只给数据添加一个头标识是UDP协议,就发给网络层了
  • 接收端:网络层将数据给UDP,只去掉IP报文头就传给应用层了

高效性:没有TCP复杂,头部开销小,只有8字节,TCP至少20个字节,传输报文很高效

传输方式、适用场景

  • 支持一对一传输,也支持一对多,多对多,多对一。单播、多播、广播
  • 直播、王者荣耀。用户只关心最新的画面,旧的不重要。TCP就不行,一个接收端没收到,就停了直到收到,就卡帧了

缺点:不可靠

但是没有拥塞控制,一直会以恒速发送数据,即使网络不好,也不会发送速率进行调整。弊端就是网络不好会丢包,但是实时性较强的场景,电话会议等,就很适合

TCP

头部结构

  • Sequence number,这个序号保证传输报文都是有序的,对端可以通过这个拼接报文
  • Window Size,窗口大小,表示还能接受多少字节的数据,用于流量控制
  • 标识符,一堆...

建立连接三次握手

不管是客户端、服务端,TCP建立连接后,都能发送、接收数据,所以TCP是全双工协议。

起初,两端都是CLOSED状态,通讯前,都会创建TCB。服务器创建完就进入LISTEN状态,等待客户端发送数据

  1. 第一次握手:客户端向服务端发送请求报文段,包含自身的数据通讯初始序号。发送完,客户端便进入SYN-SENT状态
  2. 第二次握手:服务端收到连接请求报文段后,如果同意,会发送一个一个应答,也会包含自身的数据通讯初始序号。发送完成后便进入SYN-RECEIVED状态,连接建立成功
  3. 第三次握手:客户端收到连接同意后,还要向服务端发送一个确认报文。发完这个报文段后进入**ESTABLISHED(已建立)**状态,服务端收到也进入ESTABLISHED,连接建立成功

第三次握手可以包含数据,通过快速打开(TFO)技术实现,只要涉及到握手协议,都可以使用类似TFO的方式。客户端和服务端存储相同cookie,下次握手发送cookie减少RTT的目的

为什么三次握手?

明明两次就可以? 为了防止出现失效的连接请求报文段,被服务端接收的情况,产生错误

假如场景:客户端发送一个连接请求A,由于网络超时,TCP会启动超时重传的机制再次发送一个连接请求B。此时请求顺利到达服务端,服务端应答完,建立连接,然后接收数据后释放连接。

假如此时,请求连接A在两端关闭后才到达了服务器,那么此时服务端会认为客户端又需要建立TCP连接,从而答应进入ESTABLISHED。但是客户端其实是CLOSED,就会导致服务端一直等待,浪费资源

在连接建立中,任何一端掉线,TCP都会重发一次SYN包,一般重试5次,在建立连接中可能会遇到SYN Flood攻击。遇到这种情况,可以选择调低重试次数、或者干脆在不能处理的情况下拒绝请求

断开连接四次握手

TCP是双工的,断开连接时两端都要发送FIN、ACK

  • 第一次握手:当客户端A认为数据发送完成,就需要向服务端B发送释放请求
  • 第二次握手:B收到释放资源请求后,会告诉应用层要释放TCP连接。然后会发送ACK包,并进入CLOSE_WAIT状态,此时表明A到B的链接已经释放,不再接受A发的数据。但因为是双向的,所以B还是可以发送数据给A
  • 第三次握手:B如果还有没发完的数据,还会继续发送,发送完毕后再向A发送连接释放请求,然后B就进入LAST-ACK状态。
    通过延时确认技术(通常有时间限制,否则对端会误认为重传),可以将第二、三次握手合并,延迟ACK包的发送
  • 第四次握手:A收到释放请求,向B发送确认应答,A进入TIME-WAIT状态,该状态持续2MSL(最大生存期,之报文段在网络中生存的时间,超时会被抛弃)。若该时间段内没有B发的重发请求,就进入CLOSED状态,当B收到确认应答后,也进入CLOSED
  • 为啥要进入TIME-WAIT等待2MSL时间?为了保证B能收到A的确认回答,若A发完确认后直接进入CLOSED,如果确认应答因为网络问题一直没到达,那么会造成B不能正常关闭

UDT、TCP的区别

UDP是面向无连接的,也就是说不需要传递之前,先连接起对方。 UDP只是数据报文的搬运工,不能保证有序且不丢失的传递给对方,并且UDP没有任何控制流量的算法,相对于TCP来讲,更加轻便

TCP建立连接、断开连接,都需要握手。传输过程中,通过各种算法,保证数据可靠性,没有UDP高效

Http、TLS协议

http请求内容

三部分:请求头、首部、实体 请求行由:方法、url、协议版本组成

GET /images/logo.gif HTTP/1.1

get、post区别:

  1. get请求能缓存、post不能
  2. post相对安全,get在url里,会被浏览器保存到历史记录
  3. url长度限制,会影响get,这个长度是浏览器规定的,不是RFC规定的
  4. post支持更多的编码类型,且不对数据类型限制

TLS

https通过了http传输信息,但是信息通过TLS协议做加密,TLS位于传输层,应用层之下。首次进行TLS协议传输需要两个RTT,接下来可以通过Session Resumption 减少到一个。

TLS使用两种加密技术:对称机密、非对称加密

对称加密

就是两边拥有相同的秘钥,两边都知道如何将密文加密解密。
缺点:在于如何让对方知道秘钥,因为传输数据走的是网络,如果将秘钥通过网络传递,一旦被截获就没加密的意义了

非对称加密

有公私钥之分,公钥大家都可以知道,**可以将数据用公钥加密,但是将数据解密必须要使用私钥解密。**私钥只有分发公钥的一方才知道

这种加密方式就可以完美解决对称密钥存在的问题,假设两端需要使用对称加密,那么在这之前,可以先使用非对称加密交换密钥。

简单流程:

  • 首先服务器将公钥公布出去,那么客户端也就知道公钥了。
  • 接下来客户端创建一个秘钥,然后通过公钥加密并发送给服务端
  • 服务端接收到密文以后,通过私钥解密出正确的密钥,这时候两端就都知道密钥是什么了

Http/2、Http/3

http/2相比于http/1,可以说大幅度提升了页面性能
在http/1。为了考虑性能,我们会引入雪碧图、将小图内联、使用多个域名等方式,都是因为浏览器限制了同一个域名下的请求数量,chrome一般6个
当页面请求资源很多,队头阻塞会导致在达到最大请求数量时,剩余资源等其他资源请求完,才能发起请求
http/2引入多路复用技术,该技术只通过一个TCP连接就可以传输所有请求数据。多路复用很好解决了浏览器限制同一个域名下请求数量的问题,同时也更容易实现全速传输,毕竟新开一个TCP连接都需要慢慢提升传输速度

http/2

二进制传输

http/2所有加强性能的核心点在于此。与之前http版本中,是通过文本的方式传输数据
在http/2中,引入新的编码机制,所有传输数据会被分割,并采用二进制格式编码

多路复用

http/2中,两个重要概念:帧(frame)、流(stream)
帧代表最小数据单位,每帧会标识出该帧属于哪个流,流就是多个帧组成的数据流
多路复用,就是在一个TCP连接中可以存在多个流。就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。这样可以避免http旧版本的队头阻塞,提升传输性能

http/3

虽然http/2解决了许多就问题,但还存在一个问题,是底层TCP协议的问题

因为http/2使用多路复用,一般同一域名下只需要使用一个TCP连接,当这个连接出现丢包情况,就导致http/2不如http/1了

因为在丢包的情况下,整个TCP都要等待重传,就导致后边的所有数据都被阻塞。但是对于http/1来说,可以开启多个TCP连接,出现这种情况只会影响到其中一个连接,其他的TCP连接还可正常传输

修改TCP协议解决这个问题,不太可能,因为TCP协议存在时间太长了,并且是由操作系统实现的。google另起炉灶搞了个基于UDP协议的QUIC协议,并使用在htpp/3上,http/3最大的改造就是使用了QUIC

QUIC

虽然效率很高,但是不可靠。QUIC基于UDP,但在基础上新增了许多功能,比如多路复用、O-RTT、使用TLS1.3加密、流量控制、有序交付、重传等。

多路复用

虽然Http/2也支持,但是TCP协议终究还是没有这个功能。QUIC原生就支持此功能,并且传输的单个数据流可以保证有序并不会影响其他数据流,这就解决了TCP存在的问题

并且QUIC在移动端比TCP好,因为TCP是基于IP和端口识别连接的。这种方式在多边的移动端网络环境下很脆弱。但是QUIC是通过ID的方式识别一个连接的。不管网路环境如何变,ID不变就能迅速连接上

0-RTT

通过使用类似TCP快速打开的技术,缓存当前会话上下文,在下次恢复会话时,只需将之前缓存,传递给服务器验证通过就可以传输了

http/2、http/3区别

http/2通过使用多路复用、二进制流、Header压缩等,极大提升了性能,但还是存在问题

QUIC基于UDP实现,是http/3的底层协议,又提取了TCP的精华,实现即可靠又快的协议

从输入url到页面渲染整个流程

  1. DNS解析,就是找到域名对应的ip
  2. TCP连接:三次握手
  3. 发送http请求
  4. 服务端收到请求,处理并返回
  5. 浏览器解析渲染页面

DNS解析

DNS的作用就是通过域名查询到具体的ip,DNS是基于UDP做的查询
ip存在数字、英文的组合(ipv6),不利于记忆,所以出现了域名。域名就是ip的别名,DNS就是查找域名真正的名称
TCP握手之前就已经做了DNS查询,这个是操作系统做的。
当在浏览器访问www.google.com时,会做一下操作

  • 操作系统会先在本地缓存中查询ip
  • 没有就去系统配置的DNS服务器中查询
  • 还没有,去DNS根服务器查询,这一步查询会找出负责com这个一级域名的服务器
  • 然后去该服务器查找google这个二级域名
  • 接下来三级域名的查询其实是我们配置的,你可以给www这个域名配置一个ip,然后还可以给别的三级域名配置ip?

TCP握手

应用层下发到传输层,这里TCP协议会指明两端的端口号,然后下发至网络层。网络层的ip协议会确定ip地址,并且指示了数据传输中如何跳转路由器。然后再被封装到数据链路层的数据帧结构中,最后就是物理层面的传输了

TCP握手结束后,进行TLS握手,然后正式传输数据

浏览器解析渲染页面

  • 根据html构建dom树,有css的话构建cssom树。
  • 如果遇到script,会判断是否存在async、defer,前者会并行下载并执行js,后者会先下载文件,等html解析完,再执行。如果没有,就会阻塞渲染流程知道js执行完毕,遇到文件下载回去下载文件,这里使用http/2协议的话会极大提升多图下载效率
  • dom、cssom构建完后,会生成render树,这一步就是确定页面元素布局、样式等。
  • 在生成render过程,浏览器开始调用CPU绘制,合成图层,将内容显示到屏幕