计算机网络面试重点
TCP三次握手/四次挥手 13
忽略握手过程中序列号和确认号的传输:发送的时候会随机生成一个序列号,另一段回复的时候需要回复确认号为收到的序列号加1,并且带上自己的序列号
初始序列号是用来给发送的数据包编号的,如果另一段发来了一个确认号,说明这个号之前的数据包都被接受了
三次握手建立连接
第一次握手:客户端发送一个SYN为1的数据包给服务端
第二次握手:发送一个SYN/ACK都为1的数据包给客户端
第三次握手:客户端发送一个ACK为1的数据包给服务端
可以两次握手吗?
不可以,
首先,两次握手无法保证客户端正确接收到了第二次握手的报文,这样无法完成初始序列号的互换,双方无法确认自己发送的信息能被对方接收到。
其次,如果客户端之前发送过一次连接请求,但是阻塞在网络中,过一段时间后到达服务端了,服务端会以为是客户端又要建立一条连接。如果没有三次握手,server发送了确认报文就建立了连接,但客户端因为并没有发送请求,所以不会理会,这条连接并不会有数据传输;但是三次握手如果服务端发送后没有收到客户端的确认报文,就知道 client 没有要求建立连接,这条连接不会被建立。
可以四次握手吗?
可以,但没必要。四次握手就是把第二次握手的 ACK 和 SYN 分开发,这样降低传输效率
如果客户端的ACK没有送达服务器?
服务器会以为客户端没有收到第二次发送的报文,所以会重新发送报文(默认重发五次,之后连接关闭),客户端收到后会重新发送确认报文给服务端
四次挥手释放连接
看链接吧 [https://github.com/wolverinn/Waking-Up/blob/master/Computer Network.md](https://github.com/wolverinn/Waking-Up/blob/master/Computer Network.md)
为什么要等待2MSL
- 让TCP两端发出的报文都在网络中消失,保证下一次TCP连接不会受这些残留报文干扰
- 防止ACK没有送达,2MSL是发出去的ACK报文存活时间加上服务端重发FIN的存活时间的和。如果在这个时间内都没有重新收到FIN,就当作ACK被成功接收
HTTPS握手过程 12
数字签名:对信息先用哈希算法计算得到一个摘要,再用密钥加密,放到要发送的信息后面,一起发给客户端。客户端收到后,先用公钥机密得到摘要,然后对信息使用哈希算法也计算一个摘要,比较两个摘要是否相同,如果相同就说明没有被篡改
数字证书:为公钥做认证。用CA私钥进行加密的文件,其中包含了网站公钥、网站域名、证书颁发机构、有效期等信息
握手过程
- 客户端发送一个 client hello 消息向服务器发起握手请求,其中包含了客户端支持的TLS版本和密码组合,还有一个 client random 随机字符串
- 服务器发送 server hello 进行回应,其中包含了服务器选择的密码组合,数字证书和 server random 随机字符串,其中数字证书包含了加密公钥、网站域名、证书颁发机构、有效期等信息
- 客户端认证证书,包括证书是否过期,CA是否可靠,验证数字签名,其中的域名是否和网站真实域名相符
- 客户端向服务端发送发送另一个随机字符串 premaster secret,这个字符串使用服务器公钥进行加密
- 服务器用私钥解密得到 premaster secret
- 客户端和服务端使用 client random,server random,premaster key通过相同算法计算得到 key,用于后面的对称加密
- 客户端就绪,发送用密钥加密的 finished 信号
- 服务端就绪,发送用密钥加密的 finished 信号
- 握手完成,双方用对称加密进行通信
认证证书
认证证书
为防止中间人攻击
- 验证证书的颁发机构是否可靠,来源是否可靠
- 域名是否匹配,是否还在有效期
- 判断证书是否被篡改
- 判断证书是否被吊销
中间人攻击
- 中间人拦截客户端的请求,返回自己的证书,让客户端以为自己在和正规网站通信,其中是在和中间人服务器通信
- 中间人获取客户端的通信信息,假装是客户端,与正规网站进行通信
- 中间人同时肩负两个身份,对于(真)客户端来说,它是(假)正规网站;对于(真)正规网站来说,它是(假)客户端。它同时与(真)客户端和(真)正规网站建立起两条不同的对称加密通道
主要原因是证书的伪造,所以需要CA来认证,让客户端浏览器能检测到伪造的证书
对称加密和非对称加密优缺点
- 对称加密:加密解密采用同一份密钥
- 非对称加密:需要两个密钥,一个公钥一个密钥,如果用公钥加密,只能用私钥解密
- 区别:对称加密速度快,常用语大规模数据的加密;非对称加密更安全(没有传输私钥的风险)
DNS解析 10
过程 为什么用UDP
DNS 是作为因特网上 域名和IP地址互相映射的一个分布式数据库
解析过程
- 输入一个域名,电脑发送DNS请求到本地域名服务器
- 本地域名服务器先查询缓存,如果有记录就直接返回
- 如果没有,就直接向根域名服务器发送查询请求,然后根域名服务器返回给本地域名服务器一个所查询域的主域名服务器地址
- 本地域名服务器再向上一步返回的域名服务器发送请求,然后对应的域名服务器查询自己的缓存,如果没有相关记录,就返回下一级的域名服务器地址
- 重复上一步,直到找到记录
- 本地域名服务器把返回的结果存入缓存,并将结果返回给主机
主机向本地域名服务器查询一般都是 递归查询
本地域名服务器向根域名服务器的查询是 迭代查询
为什么用UDP
访问网站的响应时间也包括了 DNS解析时间 ,要尽可能减少解析花费的时间,也要减少对 DNS 服务器的压力
一次 UDP 名字服务器交换可以短到两个报:一个查询包、一个响应包
一次TCP交换则至少包含9个包:三次握手、四次挥手加上查询包和响应包
考虑到效率原因,TCP连接开销大,所以用UDP
HTTP/HTTPS区别 9
- 端口号:HTTP是80端口,HTTPS是443端口
- 安全性:HTTP是明文传输,有中间人攻击、信息篡改、伪装等安全隐患,HTTPS建立在SSL之上,有加密和认证机制,更安全
- HTTPS由于加密解密会带来额外开销;通信需要证书要向CA购买
TCP/UDP区别 9
- 如果把UDP加上建立连接断开连接机制和报文序号,它是否就变成了TCP (还有差错检验、流量控制、阻塞控制)
- TCP传输过程中丢包怎么办
- TCP是面向连接的,UDP是无连接的(UDP发送前不需要建立连接)
- TCP是可靠的,UDP不可靠(收到UDP报文后不需要给出任何确认)
- TCP只支持点对点;UDP支持一对一、一对多、多对一、一对多
- TCP是面向字节流的,发送数据时以字节为单位,一个数据包可以拆分成若干组发送;UDP是面向报文的,一个报文只能一次发完
- TCP有拥塞控制,UDP没有,所以网络拥塞不会造成源主机发送率降低,对实时应用更友好
- TCP 还有确认、窗口、重传等功能,UDP没有的,只是单纯地发送数据包
- 报文头部大小,TCP为20字节,UDP为8字节
UDP一般用于即时通讯,语音,视频,直播等;TCP用于文件传输,邮件传输
输入URL到显示页面的过程 7
- 浏览器查询DNS,获取域名对应的IP地址,具体过程包括
- 搜索浏览器自身DNS缓存、操作系统DNS缓存、读取本地Host文件、向本地DNS服务器进行查询
- 对于向本地DNS服务器进行查询,如果要查找的域名在本地可以被解析,就将解析结果返回,否则就发起递归查询或者迭代查询
- 浏览器获得域名的IP地址后,向服务器请求建立连接,发起三次握手
- TCP/IP链接建立起来以后,浏览器向服务器发送HTTP请求
- 服务器接收到HTTP请求,根据路径参数映射到特定的处理器进行处理,并将结果和视图返回给浏览器
- 浏览器解析并渲染视图,若遇到对 JS/CSS 等静态资源的应用,就重复上述步骤向浏览器请求资源
- 浏览器根据请求到的资源渲染页面,最终呈现一个完整的页面
五层/七层模型/ TCP/IP四层 7
哪几层,每一层有哪些协议
对四层、五层的理解
主机A向服务器B传输数据包的完整过程,越详细越好
OSI七层:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
五层结构:物理层、数据链路层、网络层、传输层、应用层(会话层、表示层、应用层)
TCP/IP四层:网络接口层(物理层、数据链路层)、网际层(网络层)、传输层、应用层(会话层、表示层、应用层)
应用层协议
定义了应用进程间的通信和交互规则
HTTP STMP 都有各自不同的通信规则,数据构成不一样
应用层交互的数据单元称为报文
- HTTP 80端口
- FTP 20/21端口 20是数据连接,传输文件;21是控制连接,用来建立连接
- SSH 22端口 远程连接
- TELNET 23端口 远程连接
- STMP 25端口 发送邮件
- POP3 110端口 接收邮件
- DNS 53端口 域名解析
传输层协议
负责向两台主机之间的通信提供通用的数据传输服务
不管应用层的通信规则如何,最终信息都要用一种方式传输,这种通用方式就是传输层的两个协议决定的
传输报文段
- TCP
- UDP
网络层协议
两个计算机之间可能会经过很多数据链路和通信子网,网络层就是要选择合适的网间路由和交换节点,把数据在子网之间传送,因为网络层使用IP,所以数据格式是 IP数据报
- IP
- ARP
- ICMP
数据链路层
两台主机之间数据的传输,是在一段一段的链路上传送的
将网络层下来的 IP数据报 封装成 帧
物理层
物理层是实现相邻计算机节点之间比特流的透明传输,避免传输介质和物理设备的差异
传输的是比特流
主机A向服务器B传输数据包的完整过程
- 应用层:主机A向主机B发送一个HTTP请求报文
- 传输层:HTTP使用的TCP协议,所以HTTP请求报文按序号被封为多个报文段,并对每个报文段进行封装。A主机使用本地一个大于1024的随机TCP源端口,建立到目的服务器80端口的连接,添加TCP源端口和目的端口到报文中
- 网络层:到达网络层后,封装网络层头部,加上源IP地址和目的IP地址,封装成IP数据报,用户通常使用域名来访问服务器,这时候就需要DNS服务来查找IP地址
- 数据链路层:到达数据链路层,封装帧的头部,加上源MAC地址和目的MAC地址。根据目的 IP 地址,如果在本地网络,并且 ARP 缓存中有到对应 MAC 地址的映射,就将目的 MAC 地址置为该地址,如果不是,就要找到对应的路由器转发到另一个子网。
- 物理层:到达物理层,转成二进制的比特流,从PC1网卡发送出
GET和POST区别 4
HTTP对两者的规定是
- GET 主要用于获取资源;POST 用于提交数据,可能改变服务器资源
- GET是幂等的,同样的请求发送一次和发送多次效果一样;POST不是幂等,多次发送同一条请求可能导致添加多条数据
- GET的参数经常作为查询字符串出现在URL之后,只能是ASCII字符,长度受限制;POST请求的数据在请求体里,数据类型不受限制,长度不受限制
- GET可以被缓存和保留在浏览器中;POST不可以
但是其实本质上没有区别,只是报文格式不同。他们是HTTP的两种请求方式,但是HTTP是基于TCP/IP的,所以是在同一个传输层协议下。
正因为它们有这样的区别,所以不应该且不能用 GET 请求做数据的增删改这些有副作用的操作。因为get请求是幂等的,在网络不好的隧道中会尝试重试。如果用get请求增数据,会有重复操作的风险,而这种重复操作可能会导致副作用
在使用 XMLHttpRequest 的 POST 方法时,浏览器可能会先发送 Header 再发送 Data 分两次传输
TCP如何实现可靠传输 4
- 校验和,如果收到的校验和有差错,说明数据在传输过程中有变化,就丢弃报文,不发送确认
- 数据包按序接受,TCP报文有序列号,接收方会按序接收报文
- 丢弃重复数据
- 应答机制,接收方接受了数据之后,会发送确认报文
- 超时重传,如果已发送的报文在一定时间内没有收到确认,就重传这个报文
- 流量控制,确保接收方能接受发送方发来的数据,不会溢出
消息队列 4
常见模式
- 点对点
生产者把消息发送到 queue,消费者从 queue 中取出信息进行消费。消息被消费之后就不再存储在 queue 中,也就是说一个消息只能被一个消费者消费
支持此模式的是 RabbitMQ
- 发布/订阅
生产者把消息发送到 topic 中,该消息会被所有订阅者消费
支持此模式的 RabbitMQ、Kafka
而非消息队列的观察者模式是同步的,发送消息之后,要同步等待接收者接收数据后才能进行之后的操作
使用消息队列的好处
-
异步处理
发送者把消息发送给消息队列后可以立即返回进行其他操作,消息接收者从队列中订阅消息后会异步处理
-
应用解耦
使用消息队列后,一个模块只要向消息队列发送信息,其他模块可以选择性从消息队列中订阅消息。这样就不需要模块与模块之间直接进行通信,模块与模块之间的耦合度就很低
-
流量削峰
碰到流量高峰时,超过系统处理能力的消息都会被积压在消息队列中,系统只要按照自己能力从消息队列中取消息,就能保证在短暂的高峰中不会崩溃。高峰过后,系统就会很快把消息队列中积压的消息消费掉
RabbitMQ 和 Kafka
- 吞吐量:Kafka 吞吐量大于 RabbitMQ。Kafka 10万级,RabbitMQ 万级
- 时效性:RabbitMQ 延迟比 Kafka 低。RabbitMQ 微秒级,Kafka 毫秒级
如何保证高可用
RabbitMQ:镜像集群,queue 里的信息存在于所有 RabbitMQ 节点中,所以其中一个服务器宕机,消息也不会丢失
Kafka:由多个 broker 组成,一个 topic 被分为多个 partition,每个partition存在于多个 broker 中。并且每个 partition 在另一台机器的 broker 进程中有副本,所以有一个broker 宕机,可以用副本来代替
ARP协议 4
因为主机之间通信需要经过数据链路层,IP数据报的源地址和目的地址始终不变,但是MAC地址随着链路的改变而改变。ARP实现由IP地址得到MAC地址
每个主机都有一个ARP高速缓存,里面有本局域网各主机IP地址到MAC地址的映射表
如果主机 A 知道主机 B 的 IP 地址,但是高速缓存中没有该 IP 地址到 MAC 地址的映射,就在局域网中广播发送 ARP 请求,B 主机收到后会告知 A 他的 MAC 地址,然后 A 将 B的 IP 地址到 MAC 地址的映射加入到高速缓存中
如果目的主机和源主机不在同一个局域网,就要通过ARP找到位于该局域网上某个路由器的 MAC 地址,然后把分组转发给路由器,让路由器转发给下一个网络
ARP欺骗
类似于中间人攻击,当有 A 主机发送 ARP 广播请求 B 主机的 MAC 地址时,C 主动报上自己的 MAC 地址,让数据报先经过 C 再经过 B
HTTP常用状态码 3
常见的状态码
- 2xx状态码:200 OK 操作成功 / 206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。
- 3xx状态码:301永久重定向 /302 暂时重定向 / 304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果满足条件,表示缓存资源是最新的,则服务器会返回 304 状态码。
- 4xx状态码:客户端错误 400 Bad Request / 401 Unauthorized / 403 Forbidden / 404 Not Found
- 5xx状态码:服务端错误 500 服务器内部错误 / 503 服务不可获取
TCP阻塞控制 3
慢启动
一开始先把拥塞窗口设为一个最大报文段的大小,每收到一个新的确认报文,就把窗口加1。每经过一个传输轮次,拥塞窗口大小就会加倍,1,2,4,8……
拥塞避免
当拥塞窗口大小达到慢开始门限,开始执行拥塞避免算法,拥塞窗口大小每轮传输只增加1
无论慢启动还是拥塞避免阶段,如果网络出现拥塞,就要把慢开始门限设置为出现拥塞时发送窗口大小的一般,然后拥塞窗口重置为1,执行慢启动算法
快重传
要求接收方在收到一个思绪报文段就立即发出重复确认。发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文,而不必等待重传计时器时间到期
快恢复
当发送方连续收到三个重复确认,就把慢启动门限设置为拥塞窗口的一半,并把拥塞窗口设置为慢启动门限(+3),然后开始拥塞避免算法。不执行慢启动是因为如果可以收到好几个重复确认,就认为当前网络没有出现阻塞
TCP 粘包
TCP 是面向字节流的,本身没有数据包的概念,不会按照数据包发送数据。为了提高带宽的利用率,TCP 协议可能会将多个应用层报文合并成一个 TCP 报文段进行传输,当接受方读取时会发现不相关的数据出现在同一个 TCP 报文段中。
为了实现 TCP 的拆分和重组,需要定义应用层消息的边界。可以统一应用层消息的大小,或者在应用层协议头中增加一个表示长度的字段。
HTTP请求 2
有哪些方法,头部报文格式
- GET 获取资源
- HEAD 获取报文首部
- POST 传输数据
- DELETE 删除数据
- PUT 用于修改资源 - 完全替代原始资源
- PATCH 修改资源 - 允许部分修改
头部报文格式
- 方法名 URI路径 HTTP版本
- Host名
- 首部信息
- 请求报文:Accept-language / Accept-encoding 等
- 响应报文:Content-type / Content-length 等信息
- PUT / POST 的传输主体信息
端口号和服务 2
- HTTP 80端口
- SSH 22端口 远程连接
- TELNET 23端口 远程连接
- STMP 25端口 发送邮件
- POP3 110端口 接收邮件
- DNS 53端口 域名解析
HTTP 1.1 和 2.0 区别 2
HTTP 2.0
- 二进制分帧,将传输的报文分为 Headers 帧和 Data 帧,都是二进制格式的(之前都是文本传输)
- 多路复用,并行请求。基于二进制分帧,所有消息都是从同一个TCP连接传输,一个 TCP 连接可以承载多个双向数据流,来自不同数据流的 HTTP 消息被分解为独立的帧,交错发送,接收端根据帧头的标识符将信息重新组装
- 客户端推送,在客户端请求资源时,服务端会将相关资源一起发送给客户端,客户端就不需要再次发起请求了。例如请求一个网页,服务端会把一些静态资源一起发送
- 首部压缩,要求客户端和服务端维护一个包含之前见过的首部字段的表,以后就只发送索引号,避免重复传输;此外还使用霍夫曼编码对首部字段进行压缩
HTTP 1.1
- 支持长连接,建立一次 TCP 可以进行多次 HTTP 通信。在一个TCP中可以不用等待前一个结果返回就发送下一个 HTTP 请求。但是响应还是按顺序返回的,需要等到第一个请求返回响应才会再返回第二个,会导致队头阻塞。
- 支持打开多个 TCP 连接。客户端可以通过多个 TCP 连接实现高并发
- 支持断点传输,分块传输
- 相比 1.0 增加更多请求头和响应头
HTTP 1.0
- 需要使用 keep-alive 参数告诉服务器建立 TCP 长连接,否则默认情况下连接无法复用,每次请求都要重新建立TCP连接
HTTP缓存策略
HTTP 1.1 通过 Cache-control 来控制缓存
- no-store 禁止缓存
- no-cache 强制缓存服务器向源服务器确认缓存有效性
缓存过期 可以通过设置 max-age 和 Expired 实现
缓存验证 可以使用 ETag 首部,用 If-None-Match 判断缓存资源和最新资源 ETag 是否一致;或者用 If-Modified-Since 来验证缓存是否有效
其中 Expired,Last-Modified,If-Modified-Since 是 HTTP 1.0就有的
Cache-Control,ETag,If-None-Match 是1.1 新增
cookie/session
Session 是服务端用来记录用户状态的机制,为特定的用户创建特定的 session,用于标示和跟踪这个用户
Cookie 是客户端用来保持状态的机制,用来记录用户的一些信息,是保存在本地的一小段文本,随着每次请求发送到服务器。Cookie 中保存了 Session ID,通过这个Session ID,服务端就能识别用户。如果Cookie被禁用,会把sessionid参数附在URL中,服务端根据此来识别用户。Cookie 还可以用来保存用户登陆时的用户名等信息,或者用来分析用户行为。
Session 共享
- 主从服务器进行 session 同步,用户在主服务器登陆后,将 session 信息传递到各从服务器
- 集群统一管理 session,应用把 session 信息放到集群,需要 session 时从集群服务器上读取
- 一种实现是用 memcached-session-manager,以 tomcat 插件的形式部署在服务器,直接在 memcached 中创建和更新 session
TCP出现大量CLOSE_WAIT原因
DNS劫持原理
路由过程和算法
路由过程
- 从数据报首部提取出目的主机IP地址D,得到目的网络地址N
- 如果网络直接与路由器相连,直接交付
- 如果路由表中有到D的特定主机路由,就传送给指明的下一跳路由器
- 如果有到达N的路由,就传送给指明的下一跳路由器
- 如果有默认路由,就转发给默认路由器
- 报告转发出错
算法
狄杰斯特拉最短路径
距离向量算法
RIP
- 是应用层协议
- 是一种基于距离向量的路由选择协议,距离是指跳数,直接相连的路由器跳数为1,跳数超过15表示不可达
- 距离向量算法:
- 对地址为 X 的相邻路由器发来的 RIP 报文,先修改报文中的所有项目,把下一跳字段中的地址改为 X,并把所有的距离字段加 1;
- 对修改后的 RIP 报文中的每一个项目,进行以下步骤:
- 若原来的路由表中没有目的网络 N,则把该项目添加到路由表中;
- 否则:若下一跳路由器地址是 X,则把收到的项目替换原来路由表中的项目;否则:若收到的项目中的距离 d 小于路由表中的距离,则进行更新(例如原始路由表项为 Net2, 5, P,新表项为 Net2, 4, X,则更新);否则什么也不做。
- 若 3 分钟还没有收到相邻路由器的更新路由表,则把该相邻路由器标为不可达,即把距离置为 16。
- 按固定的时间间隔仅和相邻路由器交换自己的路由表,经过若干次交换之后,所有路由器最终会知道到达本自治系统中任何一个网络的最短距离和下一跳路由器地址。
OSPF
- 使用最短路径优先算法
- 向本自治系统的所有路由器发送信息,是泛洪法
- 发送的信息是与相邻路由器的链路状态,链路状态包括与哪些路由器相连以及链路的度量,度量用费用、距离、时延、带宽等来表示。
- 只有链路状态发生变化,才会发送信息
其他
数据链路层有保证可靠性的操作吗?
数据链路层的差错控制: 循环冗余校验CRC,只实现无比特差错传输,不提供可靠传输
ps:无比特差错与无传输差错区别:无传输差错还包括帧丢失、帧重复、帧失序等。
要实现可靠传输,还需要有帧编号,确认机制和重传机制
(由于 IP 协议 中使用了 ARP 协议,因此通常将 ARP 协议归为网络层协议。
但 ARP 协议的用途是从网络层使用的 IP地址 中解析出在数据链路层使用的硬件地。其消息由数据链路层协议封装,它是在同一局域网内部通信的,从不跨网络节点路由。因此,也可以认为 ARP 协议是数据链路层协议。)
安全相关
XSS
在提交数据的位置加入代码,将代码嵌入到页面当中,从而盗取一些信息
防御
- 对重要的 cookie 设置 httpOnly,防止客户端通过 document.cookie 读取 cookie
- 对输入内容的特定字符进行转码
CSRF
用户在正常登陆 A 网站且没有退出的情况下,打开了 B 恶意网站,该网站悄悄让用户去访问 A 网站的某个接口,在用户不知情的情况下,带着合法的登陆状态访问了某个接口,并完成操作。
防御
- 双重 Cookie 验证,因为恶意网站无法获取 cookie 信息,将 cookie 中的参数取出来加入到请求参数中,服务端进行校验
SQL 注入
把 SQL 命令插入到 表单窗口 或者 URL 的查询字符串中,欺骗服务器执行恶意的 SQL 语句
防御
- 对客户端数据的数据进行检查