前言
被问起的时候总是两三句话就结束了。这一次想好好总结,描述我所知道的流程。
过程
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
状态。
后记
这个问题能反映出对计算机的网络的了解,其实算是一个能扯很久的问题。