参考资料:
1. 小林coding
2. 50道经典计算机网络面试题
3. 一文搞定所有计算机网络面试题
4. 计算机网络面试题
文章目录
- 七层网络结构和五层网络结构
- 三次握手
- 四次挥手
- 流量控制 - 滑动窗口机制
- 拥塞控制
- TCP和UDP的区别
- TCP报文头部有那些字段,作用是什么?
- HTTP和HTTPS的区别
- HTTP 的POST和GET有哪些区别?
- HTTP 请求包含哪几个部分
- session 和 cookie 的区别
- 为什么 session 比 cookie 安全
- IO多路复用中 select、poll、epoll的区别
- DNS解析过程
- 什么是 CSRF 攻击?如何避免?
- 五层网络结构体系中,每一层对应的网络协议有哪些?
- 常见的协议和对应的端口
- IP地址有哪些分类?
- ARP 协议(IP->MAC映射)
- ping 的工作原理是什么?
- HTTP 1.1 如何优化
- 对比 HTTP1.0、HTTP1.1、HTTP2、HTTP3
- HTTPS 如何优化
- 什么是socket?
- 桥接模式和 NAT 模式的区别
七层网络结构和五层网络结构
三次握手
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。
第一次握手(SYN=1, seq=x),发送完毕后,客户端就进入SYN_SEND状态。
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1), 发送完毕后,服务器端就进入SYN_RCV状态。
第三次握手(ACK=1,ACKnum=y+1),发送完毕后,客户端进入ESTABLISHED状态,当服务器端接收到这个包时,也进入ESTABLISHED状态。
四次挥手
第一次挥手(FIN=1,seq=u),发送完毕后,客户端进入FIN_WAIT_1状态。
第二次挥手(ACK=1,ack=u+1,seq =v),发送完毕后,服务器端进入CLOSE_WAIT状态,客户端接收到这个确认包之后,进入FIN_WAIT_2状态。
第三次挥手(FIN=1,ACK1,seq=w,ack=u+1),发送完毕后,服务器端进入LAST_ACK状态,等待来自客户端的最后一个ACK。
第四次挥手(ACK=1,seq=u+1,ack=w+1),客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入TIME_WAIT状态,等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态。服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。
挥手为什么需要四次?
服务端在接收到FIN的时候,并不会立即结束,先回复一个ACK报文确认,等服务端所有相关的报文发送完了,才发送FIN报文,不能和ACK一起发送,所以需要四次挥手
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
四次挥手释放连接时,等待2MSL的意义?
①保证客户端发送的最后一个ACK报文段能够到达服务端。
因为客户端最后发送的ACK可能会丢失,如果客户端不等待直接释放的话,可能会导致服务器不能正常关闭。所以等待2MSL的意义在于有充分的时间进行超时重传,最后客户端和服务器都能正常关闭。
②防止“已失效的连接请求报文段”出现在后续连接中。
客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
流量控制 - 滑动窗口机制
拥塞控制
①慢启动
慢启动算法,表面意思就是,别急慢慢来。它表示TCP建立连接完成后,一开始不要发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个ACK,就将拥塞窗口cwnd大小就加1(单位是MSS)。每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。
发送方开始时发送一个报文段,然后等待 ACK。当收到该 ACK时,拥塞窗口从1增加为2,即可以发送两个报文段。当收到这两个报文段的 ACK 时,拥塞窗口就增加为4。这是一种指数增加的关系。
②拥塞避免算法
拥塞避免算法和慢启动算法是两个不同的算法,但是他们都是为了解决拥塞,在实际中这两个算法通常在一起实现的。相对于慢启动算法拥塞避免算法多维护了一个慢启动阈值ssthresh
当cwnd < ssthresh 时,拥塞窗口使用慢启动算法,按指数级增长。当cwnd > ssthresh时,拥塞控制使用拥塞避免算法,按线性增长。
拥塞避免算法每经过一个RTT,拥塞窗口增加 initcwnd
③拥塞发生
当网络拥塞发生丢包时,会有两种情况:
- RTO超时重传
- 快速重传
RTO超时重传
如果是发生了ROT超时重传,就会使用拥塞发生算法,修改慢启动阈值:ssthresh = cwnd / 2,cwnd 重置为1,进入慢启动过程。
快重传
有时候拥塞比较轻微,只有少量包丢失,后续的包能够正常到达。当后续的包到达接收方时,接收方会发现其Seq号比期望的大,所以它每收到一个包就Ack一次期望的Seq号,以此提醒发送方重传。当发送方收到3个或以上重复确认(Dup Ack)时,就意识到相应的包已经丢了,从而立即重传它。这个过程称为快速重传。
④快速恢复
当发生了快重传,就没必要像超时重传那样处理拥塞窗口了,应为此时的拥塞并不是很严重。此时设置慢启动阈值 ssthreh = cwnd / 2,拥塞窗口cwnd = ssthreh + 3。
TCP和UDP的区别
TCP报文头部有那些字段,作用是什么?
16位端口号:源端口号,主机该报文段是来自哪里;目标端口号,要传给哪个上层协议或应用程序
32位序号:一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。
32位确认号:用作对另一方发送的tcp报文段的响应。其值是收到的TCP报文段的序号值加1。
4位头部长度:表示tcp头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。
6位标志位:URG(紧急指针是否有效),ACk(表示确认号是否有效),PSH(缓冲区尚未填满),RST(表示要求对方重新建立连接),SYN(建立连接消息标志接),FIN(表示告知对方本端要关闭连接了)
16位窗口大小:是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
16位紧急指针:一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。
HTTP和HTTPS的区别
- HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL/TLS+HTTP) 数据传输过程是加密的,安全性较好;
- HTTP不需要证书,HTTPS需要证书;
- HTTP 建立连接比较快,只需要3次握手;HTTPS 除了3次握手还有 SSL/TSL 握手的9个包,一共是12个包;
- HTTP端口是80,HTTPS的端口是443
HTTP 的POST和GET有哪些区别?
其他请求方式和用途:
HTTP 请求包含哪几个部分
HTTP 请求报文由请求行、请求头部、请求数据和空行(可无)4个部分组成,最少包含三个部分。
-
请求行
包括请求方法、URL、HTTP协议版本,如:GET /index.html HTTP/1.1 -
请求头(key-value形式)
- User-Agent:产生请求的浏览器类型。
- Connection:连接方式(close 或 keepalive)
- Accept-Encoding:客户端可接受的编码压缩格式
- Host:主机地址
-
请求数据(key-value形式)
如POST提交的数据 -
空行
发送回车和换行符,通知服务器以下不再有请求头。
session 和 cookie 的区别
- 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
- 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
- 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
- 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
- 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。
为什么 session 比 cookie 安全
cookie 是显示的,没有被加密,容易被截获。
sessionid:
- session 是放在cookie 中的,想要获得 session 必须先截获 cookie;
- cookie 里面不常有 sessionID,只有在启动 session_start 才会有,所以每次拦截的 cookie 里面存在 sessionID 概率很小;
- sessionID是加密的,伪造很难。
- session过期之后,上一次的sessionID也会失效。
IO多路复用中 select、poll、epoll的区别
参考资料:
【操作系统】I/O 多路复用,select / poll / epoll 详解
IO多路复用,select、poll、epoll区别
select
执行过程:
- 用户线程调用select,将fd_set从用户空间拷贝到内核空间
- 内核在内核空间对fd_set遍历一遍,检查是否有就绪的socket描述符,如果没有的话,就会进入休眠,直到有就绪的socket描述符
- 内核返回select的结果给用户线程,即就绪的文件描述符数量
- 用户拿到就绪文件描述符数量后,再次对fd_set进行遍历,找出就绪的文件描述符
- 用户线程对就绪的文件描述符进行读写操作
优点:
- 所有平台都支持,具有良好的跨平台性
缺点:
- 每次调用 select。都需要将fd_set从用户空间拷贝到内核空间,当fd很多时,这个开销很大。
- 将fd_set从用户空间拷贝到内核空间,内核空间也需要对fd_set遍历一遍,来找到对应的就绪的 fd
- 最大连接数(支持的最大文件描述符数量)有限制,一般为1024
poll
执行过程(基本与select类型)
- 用户线程调用poll系统调用,并将文件描述符链表拷贝到内核空间
- 内核对文件描述符遍历一遍,如果没有就绪的描述符,则内核开始休眠,直到有就绪的文件描述符
- 返回给用户线程就绪的文件描述符数量
- 用户线程再遍历一次文件描述符链表,找出就绪的文件描述符
- 用户线程对就绪的文件描述符进行读写操作
与select的异同点
相同点:
- 内核线程都需要遍历文件描述符,并且当内核返回就绪的文件描述符数量后,还需要遍历一次找出就绪的文件描述符
- 需要将文件描述符数组或链表从用户空间拷贝到内核空间
- 性能开销会随文件描述符的数量而线性增大
不同点:
- select存储的数据结构是文件描述符数组,poll采用链表
- select有最大连接数限制,poll没有最大限制,因为poll采用链表存储
epoll
epoll 是对 select 和 poll 的改进,避免了"性能开销大"和"文件描述符数量限制"的两个缺点,主要特点有:
- 使用红黑树存储文件描述符集合(fd_set);
- 使用队列存储就绪的文件描述符;
- 每个文件描述符只需在添加时传入内核一次;通过事件更改文件描述符状态。
缺点:只能在Linux下工作
优点:
- 时间复杂度为 O(1),当有事件就绪时,只需要检测就绪队列中有无数据,有就直接返回
- 不需要从用户空间到内核空间频繁拷贝文件描述符集合,使用了内存映射(mmap)技术
- 当有就绪事件发生时采用回调的形式通知用户线程。
DNS解析过程
逐步查询:
- 缓存:浏览器缓存 -> 系统缓存文件 -> 路由器缓存 -> ISP DNS缓存
- 本地DNS服务器
- 根域名服务器
- 顶级域名服务器
- 权限域名服务器
什么是 CSRF 攻击?如何避免?
CSRF,跨站请求伪造(英文全称是Cross-site request forgery),是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
攻击的主要过程:
- 黑客将伪造的转账请求包含在帖子当中;
- 用户在银行网站登录的情况下,浏览帖子
- 帖子会将伪造的转装请求连同身份认证信息发送到银行网站,完成 CSRF 攻击
防御手段:
- 检查HTTP reference字段:伪造的请求reference是指向黑客自己的,只需检查reference是否是用户自己就可以避免
- 添加token校验:在HTTP请求中随机产生校验的token,服务器收到请求时,先校验token,使得黑客无法伪造。
五层网络结构体系中,每一层对应的网络协议有哪些?
常见的协议和对应的端口
IP地址有哪些分类?
IP地址=网络号+主机号。
网络号:它标志主机所连接的网络地址表示属于互联网的哪一个网络。
主机号:它标志主机地址表示其属于该网络中的哪一台主机。
IP地址分为A,B,C,D,E五大类:
- A类地址(1~126):以0开头,网络号占前8位,主机号占后面24位。
- B类地址(128~191):以10开头,网络号占前16位,主机号占后面16位。
- C类地址(192~223):以110开头,网络号占前24位,主机号占后面8位。
- D类地址(224~239):以1110开头,保留位多播地址。
- E类地址(240~255):以11110开头,保留位为将来使用
ARP 协议(IP->MAC映射)
工作流程:
- 检查自己的ARP列表
- 本地网络发送ARP请求的广播包
- 由路由器转发到其他网络进行查询
- 没有则查询失败
ping 的工作原理是什么?
Ping 是 ICMP(网络层协议) 的一个重要应用,主要用来测试两台主机之间的连通性。Ping 的原理是通过向目的主机发送 ICMP Echo 请求报文,目的主机收到之后会发送 Echo 回答报文。Ping 会根据时间和成功相应的次数估算出数据包往返时间以及丢包率。
所以 Ping 工作原理的本质就是发送 ICMP 请求报文,和接受目标的应答报文。
本地主机处理流程:
- 在本地,ping命令会构建一个ICMP数据包(构造回送请求报文)
- 将该ICMP数据包和目标IP地址给IP协议,IP协议将本地地址作为源地址,与目的地址等构造IP数据包
- 根据本地ARP缓存查找目的地址IP对应的MAC地址,如果缓存中没有则通过ARP协议找到对应IP的MAC地址。将MAC地址交给数据链路层以构造数据帧
- 经物理层发送给目的主机
目的主机处理流程:
- 目的主机接收到数据包
- 物理层接收到二进制数据流经数据链路层,按照以太网协议解析出数据帧,如果数据帧中的目标MAC地址与本机MAC地址相同,则接收该数据包,否则丢弃该数据包。
- 接收到该数据包之后,经网络层解析出IP数据包,通过IP包头中的协议字段判断出是ICMP数据包。之后解析出ICMP数据包,发现是回送请求报文(ping request)后马上构建一个ICMP回送应答报文(ping reply)
- 将封装好的ICMP数据包经网络层、数据链路层、物理层发送回源主机
HTTP 1.1 如何优化
- 避免发送HTTP请求
- 缓存:客户端会把请求以及响应数据保存在本地磁盘上,请求作为key,响应作为value,每次请求就做一次查询。
- 减少请求次数
- 减少重定向请求次数:将重定向的工作交给代理服务器完成。
- 合并请求:将多个小请求合并成一个大请求,对返回的结果进行拆分。
- 延迟发送请求:如滚动界面采用懒加载的方式。
- 减少服务器的HTTP响应的数据大小
- 无损压缩:文字、代码
- 有损压缩:图像、音频、视频
对比 HTTP1.0、HTTP1.1、HTTP2、HTTP3
HTTP1.0
HTTP1.0 是一种无状态、无连接的应用层协议
HTTP1.1
特点:
- http1.1基于文本解析,把所有请求和响应作为纯文本
- http1.1加入了缓存处理(强缓存和协商缓存)
- http1.1拥有长连接,并支持请求管道化(pipelining)
- http1.1流控制基于tcp连接。
缺陷:
- 高延迟 — 队头阻塞(Head-Of-Line Blocking)
- 无状态特性 — 阻碍交互
- 明文传输 — 不安全性
- 不支持服务端推送
HTTP2
特点:
- http2使用二进制传输,性能大幅度提升
- http2通过一个连接来多路复用
- http2拥有头部压缩(Huffman编码)
缺点:
- TCP 以及 TCP+TLS 建立连接的延时
- TCP 的队头阻塞并没有彻底解决
- 多路复用导致服务器压力上升
- 多路复用容易 Timeout
HTTP3
特点:基于 UDP 协议的“QUIC”协议
- 同样拥有头部压缩,并优化了对乱序发送的支持,也优化了压缩率
- 放弃tcp,通过udp建立,提高了连接建立的速度,降低了延迟
- tcp本身是无法解决队头拥塞,quic则解决了这个问题
- Connection ID使得http3支持连接迁移以及NAT的重绑定
HTTPS 如何优化
什么是socket?
socket 是对 TCP/IP 协议的封装,它的出现只是使得程序员更加方便地使用 TCP/IP 协议栈。socket 本身不是协议,它是应用层与 TCP/IP
协议簇通信的中间软件抽象层,是一组调用接口。
桥接模式和 NAT 模式的区别
在桥接模式下,虚拟出来的系统像是另一台独立的主机,可以访问局域网中的任意一台机器。主机网卡和虚拟机网卡的IP地址不同,但是会处于同一个网段,子网掩码、网关、DNS等参数则相同。
在NAT模式下,虚拟机只能访问主机,不能访问其他机器。如果主机能上网,那么虚拟机也可以上网。