TCP协议详解
TCP状态
- 对于建立链接的3次握手,主要是初始化 Sequence Number 的初始值这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序。
- 对于四次挥手,其实仔细看就是两次,因为 TCP 是全双工的,所以发送方和接收方都需要 Fin 和 Ack 。只不过有一方是被动的,所以看上去是所谓的4此挥手。
- 关于建立链接时SYN超时。如果server端接到了client发的SYN后回了SYN-ACK后client掉线了,server端没有收到client回来的ACK,那么,这个连接处于一个中间状态,既没成功也没失败。于是,server端如果在一定时间内没有收到的TCP会重发SYN-ACK。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才会把断开这个连接。
- 关于SYN Flood攻击。给服务器发一个SYN后下线,服务器需要默认等63s才会断开连接,就可以把服务器的SYN连接的队列耗尽。Linux下给了一个tcp_syncookies的参数,当SYN队列满了之后,TCP会通过源地址端口、目标地址端口和时间戳打造出一个特别的Sequence Number发过去,如果是攻击者,就不会有回应,正常连接就会把它发回来,就可以通过这个代码通信。
快速重传机制
包没有连续到达,就ack最后那个可能被丢了的包,如果发送方连续收到3次相同的ack,就重传
SACK方法
这样,在发送端就可以根据回传的SACK来知道哪些数据到了,哪些没有到。
TCP滑动窗口
窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。
发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。
如果发送窗口变成零时,使用ZWP技术,发送ZWP包给接收方,让接收方ack它的窗口尺寸,一般这个值会射程三次,第一次大约30-60秒。如果三次之后,还是0,有的TCP实现就会把链接中断。
拥塞避免
UDP协议详解
UDP提供不可靠服务,具有TCP所没有的优势:
- UDP无连接,时间上不存在建立连接需要的时延。空间上,TCP需要在端系统中维护连接状态,需要一定的开销。此连接装入包括接收和发送缓存,拥塞控制参数和序号与确认号的参数。UCP不维护连接状态,也不跟踪这些参数,开销小。空间和时间上都具有优势。 举个例子:
- DNS如果运行在TCP之上而不是UDP,那么DNS的速度将会慢很多。
- HTTP使用TCP而不是UDP,是因为对于基于文本数据的Web网页来说,可靠性很重要。
- 同一种专用应用服务器在支持UDP时,一定能支持更多的活动客户机。
- 分组首部开销小,TCP首部20字节,UDP首部8字节。
- UDP没有拥塞控制,应用层能够更好的控制要发送的数据和发送时间,网络中的拥塞控制也不会影响主机的发送速率。某些实时应用要求以稳定的速度发送,能容 忍一些数据的丢失,但是不能允许有较大的时延(比如实时视频,直播等)
- UDP提供尽最大努力的交付,不保证可靠交付。所有维护传输可靠性的工作需要用户在应用层来完成。没有TCP的确认机制、重传机制。如果因为网络原因没有传送到对端,UDP也不会给应用层返回错误信息
- UDP是面向报文的,对应用层交下来的报文,添加首部后直接乡下交付为IP层,既不合并,也不拆分,保留这些报文的边界。对IP层交上来UDP用户数据报,在去除首部后就原封不动地交付给上层应用进程,报文不可分割,是UDP数据报处理的最小单位。 正是因为这样,UDP显得不够灵活,不能控制读写数据的次数和数量。比如我们要发送100个字节的报文,我们调用一次sendto函数就会发送100字节,对端也需要用recvfrom函数一次性接收100字节,不能使用循环每次获取10个字节,获取十次这样的做法。
- UDP常用一次性传输比较少量数据的网络应用,如DNS,SNMP等,因为对于这些应用,若是采用TCP,为连接的创建,维护和拆除带来不小的开销。UDP也常用于多媒体应用(如IP电话,实时视频会议,流媒体等)数据的可靠传输对他们而言并不重要,TCP的拥塞控制会使他们有较大的延迟,也是不可容忍的
- UDP 支持一对一、一对多、多对一和多对多的交互通信。
HTTP协议详解
Session
使用 Session 维护用户登录状态的过程如下:
- 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
- 服务器验证该用户名和密码;
- 如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;
- 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;
- 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。
HTTPS
HTTPs 并不是新协议,而是让 HTTP 先和 SSL通信,再由 SSL 和 TCP 通信,也就是说 HTTPs 使用了隧道进行通信。
对称加密:加密解密使用同一密钥
非对称加密:通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。
HTTPS采用混合加密机制,通过非对称加密用与传输对称密钥,用对称密钥进行通信。
HTTPS具有完整性保护。HTTP 也提供了 MD5 报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算 MD5 的值,通信接收方是无法意识到发生了篡改。HTTPs 的报文摘要功能之所以安全,是因为它结合了加密和认证这两个操作。
HTTP 1.1对比HTTP 1.0
长连接
HTTP1.1可以在一个TCP连接上传送多个HTTP请求。
节约带宽
HTTP1.1支持只发送header信息,收到100信息之后,再把请求body发送到服务器
HTTP 2.0
多路复用
- 同一个域名下的所有通信都在单个连接上完成。
- 单个连接可以承载任意数量的双向数据流
- 数据流以消息的形式发送,而消息由一个或多个帧组成,可以乱序发送,因为根据帧首部的流标识可以重新组装。
请求头信息压缩
二进制分帧
HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
缺点
- TCP 以及 TCP+TLS 建立连接的延时
- TCP 的队头阻塞并没有彻底解决
- 多路复用导致服务器压力上升
- 多路复用容易 Timeout
HTTP 3.0
队头阻塞问题
队头阻塞是计算机网络中一种性能受限的现象,就是一个数据包影响了一堆数据包
队头阻塞分为HTTP层和TCP层。HTTP2.0协议的多路复用解决了HTTP层的队头阻塞问题。
TCP协议在收到数据包之后,这部分数据可能是乱序到达的,但是TCP必须将所有数据收集排序整合后给上层使用,如果其中某个包丢失了,就必须等待重传,从而出现某个丢包数据阻塞整个连接的数据使用
QUIC 的多路复用和 HTTP2 类似。在一条 QUIC 连接上可以并发发送多个 HTTP 请求 (stream)
。但是 QUIC 的多路复用相比 HTTP2 有一个很大的优势。
QUIC 一个连接上的多个 stream 之间没有依赖。这样假如 stream2 丢了一个 udp packet,也只会影响 stream2 的处理。不会影响 stream2 之前及之后的 stream 的处理
0RTT连接
RTT是指数据包一来一回的时间消耗。包括传播时延,链路时延,应用处理时延
一般来说HTTPS协议要建立完整链路包括TCP握手和TLS握手,总计至少要2-3个RTT,普通HTTP也要1个RTT才可以完成握手。
QUIC协议可以在第一个包就可以包含有效的应用数据,从而实现0RTT
但是对已第一个交互的客户端和服务端0RTT也是做不到的。
因此QUIC分为首次连接和非首次连接。
使用QUIC协议的客户端和服务端要使用1RTT进行密钥交换客户端和服务端首次连接时服务端传递了config包,里面包含了服务端公钥和两个随机数,客户端会将config存储下来,后续再连接时可以直接使用,从而跳过这个1RTT,实现0RTT的业务数据交互。
客户端保存config是有时间期限的,在config失效之后仍然需要进行首次连接时的密钥交换。
输入URL到页面加载过程详解
输入URL
DNS域名解析IP
通过域名查找IP过程:浏览器缓存 -> 系统缓存 -> 本地DNS服务器缓存
- 浏览器搜索自己的DNS缓存
- 搜索操作系统中的DNS缓存
- 搜索操作系统中的host文件
- 操作系统将域名发送到本地区域服务器(LNDS),进行查找,成功则返回结果(
递归查询
),失败则发起一个迭代DNS请求 - 本地域名服务器LDNS将得到的IP地址返回给操作系统,同时也将IP地址缓存起来
- 操作系统将IP地址返回给浏览器,同时将IP地址缓存起来
请求和响应数据
- TCP连接建立
- 发送http 请求
- 服务端处理
- 返回http 结果
- TCP连接关闭。
浏览器加载,解析和渲染
- 浏览器加载
- 解析html,生成dom树
- 解析css,生成cssom树
- 将dom树和cssom树合并,生成渲染树
- 遍历渲染树,开始布局和计算
- 绘制渲染树,显示到屏幕