[网络]在浏览器输入一个url到页面展现发生了什么

前言 被问起的时候总是两三句话就结束了。这一次想好好总结,描述我所知道的流程。 过程 DNS 向DNS发起请求,通常是udp协议,获得域名对应的ip地址。 查找顺序是:浏览器缓存 -> 操作系统缓存 -> 路由器缓存 -> ISP的DNS缓存 -> 根服务器 ARP 如果不是同一网络的地址,按照路由表找下一跳的ip,通过广播ARP请求获得下一跳mac地址,将报文发往此地址。 目标网络的网关接收到此报文后,同样发起ARP广播请求,寻找目标ip对应的mac地址,将报文发往此地址。 TCP三次握手 发送端随机选择一个端口和接收端端口之间发起三次握手,之后建立起TCP连接。 Linux执行sysctl -a|grep ip_local_port_range可以看到随机端口选择范围 MSS协商与TCP分段 MSS,Maximum Segment Size,TCP报文数据不能大于这个值,MSS = MTU - IP首部长度,20 - TCP首部长度,20 为了得出路径最小MSS,TCP一端设置IP报文DF标志(Don’t Fragment flag)告诉IP层不要分片,这样IP必须分片的时候,就会传回一个ICMP差错报文。 高级的ICMP差错报文会返回发生差错的MTU大小,如果ICMP差错报文没有带回MTU大小,需要发送端不断减少MSS并重发报文,得出合适的MSS。注意,一段时间后TCP会重新协商路径最小MSS,调整路径最小MSS。 将一个数据分组根据MSS拆成多个TCP报文,这就是TCP分段。 HTTP 建立起连接之后,发送HTTP报文。HTTP由请求行、请求头、请求主体组成。 请求行只有一行,由方法,path,协议版本,以一个\r\n结束。 请求头由多对key-value组织而成,以一个\r\n换行,以两个\r\n结束。 请求主体,包含请求的数据/响应数据。 http1.1版本加入了Connection:Keep-Alive,使得一个TCP连接可以复用多次,而不是一个请求建立起一次连接。 http2版本加入TCP多路复用。虽然http1.1版本可以复用TCP连接,但是一次只能发一个HTTP请求报文,想要并行发起多个请求,追能多建立TCP连接,而浏览器一般会限制并发6~8个连接,其余请求只能排队。加入TCP多路复用之后,减少了连接;此外http2采用了二进制传输,头部压缩大幅提高了性能。虽然二进制传输在调试过程不是很方便,但是调试工具都会帮我们转成明文格式展示。 更多信息http2可参见再谈HTTP2性能提升之背后原理—HTTP2历史解剖。本站也有启用http2。 HTTPS 如果启用用HTTPS,客户端会校验服务端的证书,根据证书和服务器协商一个对称加密算法和一个密钥,这一部分是RSA非对称加密,之后客户端和服务端会使用这个算法和密钥进行数据加密传输。HTTPS的原理出门左转TLS完全指南(一):TLS和安全通信,这文章讲了HTTPS的部分内容,主要内容是证书方面的内容;还有一部分内容看图解SSL/TLS协议,主要补充了用DH算法代替RSA进行密钥交换,避免了密钥在网络中传输。 TCP拥塞控制 TCP需要拥塞控制逻辑使用网络不好的情况,详见TCP拥塞控制那些事。 应用 关于应用层, 大多数是请求走cdn-> TCP四次挥手 发送端和接收端之间进行四次挥手断开连接,接着主动断开的端口进入FIN_WAIT_1,收到ACK报文后进入FIN_WAIT_2,收到接收端的FIN报文后最终会进入TIME_WAIT状态, 默认保持2MSL的不可用时间,防止相同五元组的连接建立后,收到上一代连接的重复报文,而产生混乱。被动断开的端口先进入CLOSE_WAIT,由服务器执行断开后发送FIN报文进入LAST_ACK状态,收到客户端ACK报文进入CLOSED状态。 后记 这个问题能反映出对计算机的网络的了解,其实算是一个能扯很久的问题。

August 21, 2019

[网络]TCP拥塞控制那些事

前言 看完了《TCP/IP详解 卷一》,对TCP/IP协议簇的认知多了一些。总结一下TCP窗口有关的慢启动、拥塞避免、快速重传、快速恢复的概念。 TCP滑动窗口 窗口有两种,通告窗口(Receiver Window,rwnd)和拥塞窗口(Congestion Window,cwnd)。 通告窗口:通告窗口表明了接收端当前的接受能力。TCP在发送端和接收端都是有缓冲区的,通告窗口声明了当前接收端的缓冲区还能接收的字节大小。这个数值会在TCP报文里携带。 拥塞窗口:拥塞窗口不被TCP报文传输,是发送端基于拥塞避免算法算出来的一个窗口。这个窗口限制了发送方的发送速率避免网络拥塞。 两个窗口共同组成了一个滑动窗口。简单来说,通告窗口是强制限制,拥塞窗口是自发限制。 有一点要注意的是,窗口的单位用字节表示,但是拥塞窗口的调整总是以一个MSS的倍数来调整。 这里用书上的图描述滑动窗口, 当一个TCP发送方发送数据的时候就会查看可用窗口能否发送(如果启用了Nagle算法,可用窗口必须大于等于一个MSS,发送方才发送数据) 上面是抓包得到的一个报文,Win=2027是一个通告窗口,表示服务器的缓冲区还能接受2027字节的数据。 拥塞控制 上图是一个tcp刚开始传输数据时的速率变化走向。 拥塞避免、慢启动、快速重传、快速恢复这四个词其实并不能单独分开讲。当一个连接的网络情况不好的时候,就会丢包或超时,这时就要降低发送方的发送速率防止恶化,这种就是拥塞控制。 这种机制涉及到cwnd和ssthresh两个指标,ssthresh是一个区分慢启动和拥塞避免的阈值,当拥塞发生时,分两种情况 超时:ssthresh = cwnd / 2(最小为2MSS),cwnd = 1MSS,进入慢启动 丢包:ssthresh = cwnd / 2(最小为2MSS),cwnd = ssthresh + 3MSS,进入快速重传 慢启动 慢启动其实是发送速率重新计算,cwnd 初始值为一个数据报大小,ssthresh初始值为65535,是一个然后在到达阈值之前,每接收到一个新的ACK,cwnd就会增加一个报文段的大小,这样子慢启动其实是以指数增加速率. 拥塞控制 上图是一个tcp刚开始传输数据时的速率变化走向。 拥塞避免、慢启动、快速重传、快速恢复这四个词其实并不能单独分开讲。当一个连接的网络情况不好的时候,就会丢包或超时,这时就要降低发送方的发送速率防止恶化,这种就是拥塞控制。 这种机制涉及到cwnd和ssthresh两个指标,ssthresh是一个区分慢启动和拥塞避免的阈值,当拥塞发生时,分两种情况 超时:ssthresh = cwnd / 2(最小为2MSS),cwnd = 1MSS,进入慢启动 丢包:进入快速重传 慢启动 慢启动其实是发送速率重新计算,cwnd 初始值为一个数据报大小,ssthresh初始值为65535,是一个然后在到达阈值之前,每接收到一个新的ACK,cwnd就会增加一个报文段的大小,这样子慢启动其实是以指数增加网速到一个比较平衡的水平。 拥塞避免 当cwnd大于等于ssthresh时进入拥塞避免状态,在一个RTT内无论收到多少ACK都只将cwnd增加一个报文大小,从时间上来看网速线性增加。 快速重传和快速恢复 快速重传指,当收到重复的3个ACK报文时(duplicate ack),设置ssthresh = cwnd / 2(最小为2MSS),cwnd = ssthresh + 3MSS,然后进入快速恢复阶段。 暂停发送新的报文,重传丢失报文。 接下来每收到重复的ACK时,将cwnd增加一个报文大小。如果cwnd大于未确认报文大小(报文丢失后我们还在发新的报文,未确认报文指丢失报文到最后一个报文之间报文总大小),可以发送新报文。 接下来如果收到新的ACK报文,将cwnd设置为ssthresh,也就是网速降为一半,并进入拥塞避免阶段。 总的来说,网速一直处于一个动态调整的过程,一个连接上cwnd随时间的变化如图所示 还有一点,上面关于cwnd的比较其实还要考虑rwnd的值,如果rwnd>cwnd,应取rwnd去比较,毕竟两者决定了可用窗口大小。...

August 15, 2019