网络层面试题
主要参考:
[面试∙网络] TCP/IP(六):HTTP 与 HTTPS 简介
[面试∙网络] TCP/IP(五):TCP 协议详解
[面试∙网络] TCP/IP(四):TCP 与 UDP 协议
[面试∙网络] TCP/IP(三):IP协议相关技术
[面试∙网络] TCP/IP(二):IP协议
[面试∙网络] TCP/IP(一):数据链路层
1. 简介TCP
和 UDP
区别,他们位于哪一层?
A. TCP
和 UDP
区别:
TCP协议:
是面向有连接
的协议,也就是说在使用TCP协议
传输数据之前一定要在发送方
和接收方
之间建立连接。建立连接后,通过数据重传
、流量控制
等功能,TCP协议
能够正确处理丢包问题,保证接收方
能够收到数据,同时还能有效利用网络带宽
。
UDP协议:
是面向无连接
的协议,它只会把数据传递给接收端,但不会关注接收端是否收到数据。
区别:
-
连接性:
TCP协议
面向有连接
的协议,要先确保发送方
和接收方
之间先建立连接才能进行通信;
UDP协议
是面向无连接
的协议,即发送数据之前不需要建立连接 -
可靠性:
TCP
提供可靠的服务,也就是说,通过TCP
连接传送的数据,可以保证无差错
、不丢失
、不重复
、且按序到达
;
UDP
尽最大努力交付,即不保证可靠交付。 -
传输内容:
TCP
是面向字节流
,TCP
把数据看成一连串无结构的字节流;
UDP
是面向报文
的,UPD
没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低。 -
服务性质:
每一条TCP
连接都是点到点
的
UPD
支持一对一、一对多、多对一
和多对多
的交互通讯 -
开销
TCP首部
开销20
字节;
UDP首部
开销小,只有8
个字节。 -
信道:
TCP
的逻辑通信信道是全双工
的可靠信道,
UDP
是不可靠信道。
B. TCP
和UDP
位于OSI七层模型
的第四层
:传输层
。
2. 路由器和交换机的工作原理大概是什么,他们分别用到什么协议,位于哪一层?
A.路由器和交换机的工作原理大概是什么
a.交换机
-
二层交换机:
交换机工作原理.png
二层交换机
是一种在数据链路层
工作的网络设备
,一般要求支持802.1q(就是划VLAN)
、SNMP
、限速
、广播风暴控制
、ACL
、组播
这些常见的功能;它有多个端口,可以连接不同的设备。交换机
根据每个帧中的目标 MAC 地址
决定向哪个端口发送数据,此时它需要参考“转发表”
转发表
并非手动设置,而是交换机自动学习得到的。当某个设备向交换机发送帧时,交换机将帧的源MAC 地址
和接口
对应起来,作为一条记录
添加到转发表
中。
下图描述了交换机自学过程
的原理:
-
三层交换机:
三层交换机
具有路由器功能
,工作在网络层
,在二层的基础上支持如静态路由
、RIP(矢量路由选择协议)
、OSPF(链路状态路由选择协议)
、BGP(边界网关协议)
、ISIS(分级的链接状态路由协议)
等路由协议,有时候会要求支持MPLS(多协议标签交换)
、GRE(通用路由封装协议)
、L2TP(工业标准的Internet隧道协议)
、IPSec(Internet 协议安全性)等隧道协议
。三层交换机上能够对分组报文根据IP地址
进行转发。
-
四到七层交换机:
负责处理OSI模型
中从传输层
至应用层
的数据。如果用TCP/IP分层模型
来表述,4-7层交换机
就是以传输层
及其上面的应用层
为基础,进行分析数据
,并对其进行特定的处理。
例如:对于并发访问量
非常大的一个企业级Web站点
,使用一台服务器不足以满足前端的访问需要,这时通常会通过多台服务器
来分担,这些服务器前端访问的入口地址通常只有一个(企业为了使用者的方便,只会向最终的用户开放一个统一的访问URL
)。为了能通过同一个URL
将前端访问分发到后台多个服务器上,可以在这些服务器的前端加一个负载均衡器
。这种负载均衡器
就是4-7层交换机
的一种。
此外,实际通信当中,人们希望在网络比较拥堵的时候,优先处理像语音这类对及时性要求较高的通信请求,放缓处理像邮件或数据转发等稍有延迟也并无大碍的通信请求,这种处理被称为宽带控制
,也是4-7层交换机
的重要功能,还有其他很多功能,例如广域网加速器
,特殊应用访问加速
以及防火墙
等。
- 路由器:
路由器
工作在网络层
,完成通过路由控制
将分组数据
发送到目标地址
的功能。支持如静态路由
、RIP(矢量路由选择协议)
、OSPF(链路状态路由选择协议)
、BGP(边界网关协议)
、EGP(外部网关协议)
、ISIS(分级的链接状态路由协议)
等路由协议。
路由器中保存着路由控制表
,它在路由控制表
中查找目标IP地址
对应的下一个路由器地址
。下图描述了这一过程:
image.png
主机A
的地址是10.1.1.30
,要把数据发往地址为10.1.2.10
的主机。在主机A
的路由表中,保存了两个字段,由于目标地址10.1.2.10
与10.1.1.0/24
段不匹配,所以它被发往默认路由10.1.1.1
也就是图中路由器1的左侧网卡的IP地址
。
路由器1
继续在它自己的路由控制表
中查找目标地址10.1.2.10
,它发现目标地址属于10.1.2.0/24
这一段,因此将数据转发至下一个路由器10.1.0.2
,也就是路由器2
的左侧网卡的地址。
路由器2
在自己的路由控制表
中查找目标地址10.1.2.10
,根据表中记录将数据发往10.1.2.1接口
,也就是自己的右侧网卡
的IP地址
。主机B
检查目标IP地址
和自己相同,于是接收数据。
3. 描述TCP 协议三次握手,四次释放的过程。
A. TCP 三次握手:
三次握手.png图片取自:TCP三次握手和四次挥手深入实践
-
第一次握手:
客户端
将标志位SYN
置为1
,随机产生一个序列值seq = x
,并将该数据包发送给服务端
,客户端
进入SYN_SENT
状态,等待服务端
确认。 -
第二次握手:
服务端·收到数据包后由
标志位SYN=1
,知道客户端
请求建立连接,服务端
将标志位SYN
和ACK
都置为1
,ack = x + 1
,随机产生一个值seq = y
, 并将该数据包发送给客户端
以确认连接请求,服务端
进入SYN_RCVD
状态。 -
第三次握手:
客户端
收到确认后,检查ack
是否为x+1
,ACK
是否为1
,如果正确将标志位ACK
置为1
,ack = y + 1
, 并将该数据包发送给服务端
,服务端
检查ack
是否为y+1
,ACK
是否为1
,如果都正确则连接建立成功,客户端
和服务端
进入ESTABLISHED
状态,完成三次握手,随后客户端
与服务端
之间开始进行数据传输。
B. TCP 四次挥手:
TCP 四次挥手.png图片取自:TCP三次握手和四次挥手深入实践
-
第一次挥手:
客户端
发出连接释放报文
,并且停止发送数据。将释放数据报文首部
的FIN
置为1
,序列号seq
置为u
(等于前面已经传送过来的数据的最后一个字节的序号加1
),此时,客户端
进入FIN-WAIT-1(终止等待1)
状态。TCP
规定,FIN
报文段即使不携带数据,也要消耗一个序号。 -
第二次挥手:
服务端
收到报文后,检查到首部的FIN
为1
,知道客户端
请求释放连接
,服务端
发出确认报文
,并将报文首部的ACK
置为1
,ack
置为u + 1
,并且带上自己的序列号v
,此时服务端进入CLOSE-WAIT(关闭等待状态)
。客户端
收到服务端
的确认报文
后,检查ACK
是否为1
,ack
是否为u+1
,如果都正确,客户端进入FIN-WAIT-2(终止等待2)
状态。等待服务端
发送连接释放报文
。 -
第三次挥手:
服务端
将最后的数据发送完毕后,就向客户端
发送连接释放报文
,FIN=1
,ack = u+1
,序列号
为seq = w
(因为在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号
为seq=w
),此时服务端
进入LASK-ACK(最后确认)
状态,等待客户端
确认。 -
第四次挥手:
客户端
接收服务器
的报文后,检查FIN
为1
,知道服务端
请求释放连接
,发出确认报文
,ACK = 1
,ack = w + 1
,seq = u + 1
, 此时客户端
进入TIME-WAIT(时间等待)
状态。服务端
只要收到客户端
发出的确认报文
,检查ACK
是否为1
,ack
是否为w + 1
, 如果都正确,立即进入CLOSE
状态。
4. TCP 协议是如何进行流量控制,拥塞控制的?
A. 如何进行流量控制:
-
流量控制
以动态调整发送空间大小(滑动窗口)
的形式来反映接收端
接收消息的能力,反馈给发送端
以调整发送速度
,避免发送速度
过快导致的丢包
或者过慢
降低整体性能。 -
这里采用
滑动窗口机制
,一是不用每次发送完成都需要等待收到确认消息才能继续发送,二是参考接收端
的接收能力,限制发送数据段
大小,避免丢失现象。
B. 如何进行拥塞控制:
- 连接建立的初期,如果
窗口
比较大,发送方
可能会突然发送大量数据,导致网络瘫痪。因此,在通信一开始时,TCP
会通过慢启动
算法得出窗口的大小,对发送数据量进行控制。
流量控制
是由发送方
和接收方
共同控制的。刚刚我们介绍了接收方
会把自己能够承受的最大窗口长度
写在TCP 首部
中,实际上在发送方
这里,也存在流量控制
,它叫拥塞窗口
。TCP 协议中的窗口是指发送方窗口
和接收方窗口
的较小值。
慢启动过程如下:
-
通信开始时,
发送方
的拥塞窗口
大小为1
。每收到一个ACK
确认后,拥塞窗口
翻倍。 -
由于
指数级增长
非常快,很快地,就会出现确认包
超时。(超时是因为数据量大导致网络拥塞) -
此时设置一个
“慢启动阈值”
,它的值是当前拥塞窗口
大小的一半。 -
同时将
拥塞窗口大小
设置为1
,重新进入慢启动过程
。 -
由于现在
“慢启动阈值”
已经存在,当拥塞窗口
大小达到阈值
时,不再翻倍,而是线性增加
。 -
随着
窗口
大小不断增加,可能收到三次重复确认
应答,进入“快速重发”
阶段。
(快速重发: 当发送端
连续收到三个重复的ack
时,表示该数据段
已经丢失,需要重发。当收到三个表示同一个数据段的ack
时,不需要等待计时器超时,即重新发送数据段(当时这三个ack要在超时之前到达发送端),因为能够收到接收端
的ack确认信息,所以数据段只是单纯的丢失,而不是因为网络拥塞
导致,) -
这时候,
TCP
将“慢启动阈值”
设置为当前拥塞窗口大小
的一半,再将拥塞窗口大小
设置成阈值大小
(也有说加 3)。 -
拥塞窗口
又会线性增加
,直至下一次出现三次重复确认
应答或超时
。
以上过程可以用下图概括:
窗口调整.png5. 为什么建立连接时是三次握手,两次行不行?如果第三次握手失败了怎么处理
A. 为什么是三次握手:
-
因为在网络请求中,我们应该时刻记住:“网络是不可靠的,数据包是可能丢失的”。
-
假设没有第三次确认,
客户端
向服务端
发送了SYN
,请求建立连接。由于延迟,服务端没有及时收到这个包。于是客户端
重新发送一个SYN
包。回忆一下介绍TCP 首部
时提到的序列号
,这两个包的序列号显然是相同的。 -
假设服务端接收到了
第二个 SYN 包
,建立了通信,一段时间后通信结束,连接被关闭。这时候最初被发送的SYN 包
刚刚抵达服务端
,服务端
又会发送一次ACK
确认。由于两次握手就建立了连接,此时的服务端
就会建立一个新的连接,然而客户端
觉得自己并没有请求建立连接,所以就不会向服务端
发送数据。从而导致服务端
建立了一个空的连接,白白浪费资源。 -
在三次握手的情况下,
服务端
直到收到客户端
的应答后才会建立连接。因此在上述情况下,客户端
会接受到一个相同的ACK 包
,这时候它会抛弃这个数据包,不会和服务端
进行第三次握手,因此避免了服务端
建立空的连接
。
B. 第三次握手失败了怎么处理
-
按照
TCP 协议
处理丢包的一般方法,服务端
会重新向客户端
发送数据包
,直至收到ACK 确认
为止。但实际上这种做法有可能遭到SYN 泛洪攻击
。所谓的泛洪攻击
,是指发送方
伪造多个 IP 地址
,模拟三次握手
的过程。当服务器
返回ACK
后,攻击方故意不确认,从而使得服务器不断重发ACK
。由于服务器
长时间处于半连接状态
,最后消耗过多的CPU
和内存资源
导致死机。 -
正确处理方法是
服务端
发送RST 报文
,进入CLOSE
状态。这个RST
数据包的TCP
首部中,控制位中的RST 位
被设置为1
。这表示连接信息
全部被初始化,原有的TCP
通信不能继续进行。客户端如果还想重新建立TCP
连接,就必须重新开始第一次握手。
6. 关闭连接时,第四次握手失败怎么处理?
实际上,在第三步
中,客户端
收到FIN 包
时,它会设置一个计时器
,等待相当长的一段时间。如果客户端
返回的ACK
丢失,那么服务端
还会重发FIN
并重置计时器
。假设在计时器
失效前服务器
重发的 FIN 包
没有到达客户端
,客户端
就会进入 CLOSE
状态,从而导致服务端
永远无法收到 ACK 确认
,也就无法关闭连接
。
示意图如下:
image.png
7. 为什么TCP握手是三次,挥手却是四次?(假设客户端主动,服务器端被动)
在TCP
三次握手中,服务器端的SYN
和ACK
是放在一个TCP报文段
中向客户端
发送的,而在断开连接的过程中,服务器端
向客户端
发送的ACK
和FIN
是是分别在两个不同的TCP
报文段中。这是因为在服务器端
接收到客户端
的FIN
后,服务器端
可能还有数据要传输,所以先发送ACK
,服务器端
把数据发完之后就可以发送FIN
断开连接了。
7. 你怎么理解分层和协议?
A. 如何理解分层
分层的理由:
-
独立性
通过分层,每一层值接受下一层提供的特定服务,并且负责为上一层提供特定服务,上下层之间进行交互所遵循的约定叫“接口”,同一层之间的交互所遵循的约定叫做“协议”。每一层可以独立使用,及时系统中某些层次发生变化,也不会波及系统。 -
灵活性好
对于任何一层的改动,只要上下层接口不变,都不会造成系统的问题,有利于每一层功能的扩展和变动。 -
易于实现和维护
将大问题简化为小问题,大系统简化为小层次。比如将网络的通信过程划分为小一些、简单一些的部件,因此有助于各个部件的开发、设计和故障排除。 -
能促进标准化工作
通过分层,定义在模型的每一层实现什么功能,有利于鼓励产业的标准化,同时允许多个供应商进行开发。
B. 分层的原则
- 各个层之间有清晰的边界,便于理解;
- 每个层实现特定的功能;
- 层次的划分有利于国际标准协议的制定;
- 层的数目应该足够多,以避免各个层功能重复
B. 如何理解协议
协议
实际上是一种通信双方共同遵守
的规范
。比如我需要把性别
和年龄
传递给另外一台主机,那么我可以定义一个"A 协议"
,协议规定数据的前 4 个字节
表示性别
,后四个字节
表示年龄
。这样对方主机
接收时就知道前 4 个字节
是性别
,而不会错把它当成年龄
来处理。
协议
的规范和共同遵守,有利于各个分层之间的交流和处理,也有利于促进协议
的标准化过程
。
8. HTTP 请求中的 GET 和 POST 的区别,Session 和 Cookie 的区别。
A. HTTP 请求中的 GET 和 POST 的区别
GET
请求通常用于查询、获取数据
,而 POST
请求则用于发送数据
,除了用途上的区别,它们还有以下这些不同:
-
GET
后退按钮/刷新无害,POST
数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 -
GET
书签可收藏,POST
为书签不可收藏。 -
GET
能被缓存,POST
不能缓存 。 -
GET
编码类型application/x-www-form-url
,POST
编码类型encodedapplication/x-www-form-urlencoded
或multipart/form-data
。为二进制数据使用多重编码
。 -
GET
历史参数保留在浏览器历史中。POST
参数不会保存在浏览器历史中。 -
GET
对数据长度有限制,当发送数据时,GET
方法向URL
添加数据;URL
的长度是受限制的(URL
的最大长度是2048
个字符)。POST
无限制。 -
GET
只允许ASCII
字符。POST
没有限制。也允许二进制数据。与POST
相比, -
GET
的安全性较差,因为所发送的数据是URL
的一部分。在发送密码或其他敏感信息时绝不要使用GET
!POST
比GET
更安全,因为参数不会被保存在浏览器历史或web 服务器日志
中。GET
的数据在URL
中对所有人都是可见的。POST
的数据不会显示在URL
中。
注意:
POST
请求仅比GET
请求略安全一点,它的数据不在URL
中,但依然以明文的形式
存放于HTTP
的请求头中。
B.Cookie 和 Session
HTTP
是一种无状态
的连接,客户端
每次读取web 页面
时,服务器
都会认为这是一次新的会话
。但有时候我们又需要持久保持
某些信息,比如登录时的用户名、密码
,用户上一次连接时的信息等。这些信息就由 Cookie
和Session
保存。
这两者的根本性区别在于,cookie
保存在客户端
上,而 session
则保存在服务器
中。由此我们还可以拓展出以下结论:
-
cookie
相对来说不安全,浏览器可以分析本地的cookie
进行cookie
欺骗。 -
session
可以设置超时时间,超过这个时间后就失效,以免长期占用服务端
内存。 - 单个
cookie
的大小有限制(4 Kb)
,每个站点的cookie
数量一般也有限制(20个)
。 -
客户端
每次都会把cookie
发送到服务端
,因此服务端
可以知道cookie
,但是客户端
不知道session
。
当服务器
接收到cookie
后,会根据cookie
中的 SessionID
来找到这个客户的 session
。如果没有,则会生成一个新的 SessionID
发送给客户端。
9. 谈谈你对 HTTP 1.1,2.0 和 HTTPS 的理解。
一、HTTP
HTTP(超文本传输协议,HyperText Transfer Protocol)
是应用层
的协议,目前在互联网中应用广泛。
它被设计用于Web浏览器
和Web服务器
之间的通信,但它也可以用于其他目的。 HTTP
遵循经典的客户端-服务端模型
,客户端打开一个连接以发出请求,然后等待它收到服务器端
响应。HTTP
是
无状态协议
,意味着服务器
不会在两个请求之间保留任何数据(状态)。
二、HTTP1.0 ——构建可扩展性
HTTP 1.0
规定浏览器
与服务器
只保持短暂的连接,浏览器
的每次请求都需要与服务器
建立一个TCP连接
,服务器
完成请求处理后立即断开TCP连接
,服务器不跟踪每个客户也不记录过去的请求。
三、HTTP1.1
——标准化的协议
HTTP/1.0
的多种不同的实现运用起来有些混乱,HTTP1.1
是第一个标准化版本,重点关注的是校正HTTP1.0
设计中的结构性缺陷:
-
连接可以重复使用,节省了多次打开它的时间,以显示嵌入到单个原始文档中的资源。
-
增加流水线操作,允许在第一个应答被完全发送之前发送第二个请求,以降低通信的延迟。
-
支持响应分块。
-
引入额外的缓存控制机制。
-
引入内容协商,包括语言,编码,或类型,并允许客户端和服务器约定以最适当的内容进行交换。
-
添加Host 头,能够使不同的域名配置在同一个IP地址的服务器。
-
安全性得到了提高
在http1.1
中,client
和server
都是默认对方支持长链接的, 如果不希望使用长链接,则需要在header中
指明connection:close
;
四、HTTP2.0——为了更优异的表现
HTTP/2.0
在HTTP/1.1
有几处基本的不同:
-
HTTP2
是二进制协议
而不是文本协议
。不再可读和无障碍的手动创建,改善的优化技术现在可被实施。 - 这是一个复用协议。并行的请求能在同一个链接中处理,移除了HTTP/1.x中顺序和阻塞的约束。
- 压缩了headers。因为headers在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
- 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。
五、HTTPS
我们知道HTTP
协议直接使用了TCP
协议进行数据传输。由于数据没有加密,都是直接明文
传输,所以存在以下三个风险:
-
窃听风险:第三方节点可以获知通信内容。
-
篡改风险:第三方节点可以修改通信内容。
-
冒充风险:第三方节点可以冒充他人身份参与通信。
比如你在手机上打开应用内的网页时,有时会看到网页底部弹出了广告,这实际上就说明你的HTTP
内容被窃听、并篡改了。
HTTPS
协议旨在解决以上三个风险
,因此它可以:
-
保证所有信息加密传输,无法被第三方窃取。
-
为信息添加校验机制,如果被第三方恶意破坏,可以检测出来。
-
配备身份证书,防止第三方伪装参与通信。
HTTPS
的结构如图所示:
可见它仅仅是在 HTTP
和TCP
之间新增了一个TLS/SSL
加密层,这也印证了一句名言:“一切计算机问题都可以通过添加中间层解决”。
使用HTTPS
时,服务端
会将自己的证书发送给客户端
,其中包含了服务端
的公钥。基于非对称加密
的传输过程如下:
- 客户端使用公钥将信息加密,密文发送给服务端
- 服务端用自己的私钥解密,再将返回数据用私钥加密发回客户端
- 客户端用公钥解密
这里的证书
是服务器
证明自己身份的工具,它由权威的证书颁发机构(CA)
发给申请者。如果证书是虚假的,或者是自己给自己颁发的证书,服务器就会不认可这个证书并发出警告:
总结一下 HTTPS 协议
是如何避免前文所说的三大风险的:
-
先用
非对称加密
传输密码,然后用这个密码对称加密数据
,使得第三方无法获得通信内容 -
发送方
将数据的哈希结果
写到数据中,接收方
解密后对比数据的哈希结果
,如果不一致则说明被修改。由于传输数据加密,第三方无法修改哈希结果。 -
由
权威机构颁发
证书,再加上证书校验
机制,避免第三方伪装
参与通信.