主要参考:
[面试∙网络] 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.交换机
-
二层交换机:
二层交换机
是一种在数据链路层
工作的网络设备
,一般要求支持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地址
对应的下一个路由器地址
。下图描述了这一过程:
主机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 三次握手:
图片取自: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三次握手和四次挥手深入实践
第一次挥手:
客户端
发出连接释放报文
,并且停止发送数据。将释放数据报文首部
的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)。拥塞窗口
又会线性增加
,直至下一次出现三次重复确认
应答或超时
。
以上过程可以用下图概括:
5. 为什么建立连接时是三次握手,两次行不行?如果第三次握手失败了怎么处理
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 确认
,也就无法关闭连接
。
示意图如下:
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 协议
是如何避免前文所说的三大风险的:
先用
非对称加密
传输密码,然后用这个密码对称加密数据
,使得第三方无法获得通信内容发送方
将数据的哈希结果
写到数据中,接收方
解密后对比数据的哈希结果
,如果不一致则说明被修改。由于传输数据加密,第三方无法修改哈希结果。由
权威机构颁发
证书,再加上证书校验
机制,避免第三方伪装
参与通信.