前言
过年倒计时~
今天是网络篇的最后一篇,网络知识也是面试常考内容,所以必须要把基础打牢。
网络十二问,送给大家。
这些问题,你能答上来吗
我总结了下网络方面会涉及到的一些问题,大家看看,如果都能答上来,那这篇文章就可以略过了。
- 网络通信的过程,以及中间用了什么协议?
- TCP连接过程,三次握手和四次挥手,为什么?
- 常用的状态码。
- 讲一下TCP协议和UDP协议的区别和场景
- socket和WebSocket
- Https的链接建立过程
- 讲解一下数字签名,为什么真实可靠
- 证书链安全机制
- 建立过程耗时,那么怎么优化呢?
- 讲一下Http和Https的区别
- Http传输图片有哪些方式
- 怎么实现分块传输,断点续传?
网络通信的过程,以及中间用了什么协议
这个问题我之前专门做了一个动画,大家可以翻到上一篇文章看看:
再简单总结下:
客户端:
- 1、在浏览器输入网址
- 2、浏览器解析网址,并生成
http
请求消息 - 3、浏览器调用系统解析器,发送消息到DNS服务器查询域名对应的
ip
- 4、拿到ip后,和请求消息一起交给操作系统协议栈的
TCP模块
- 5、将数据分成一个个数据包,并加上TCP报头形成
TCP数据包
- 6、TCP报头包括发送方端口号、接收方端口号、数据包的
序号、ACK号
。 - 7、然后将
TCP消息
交给IP模块。 - 8、IP模块会添加
IP头部
和MAC头部
。 - 9、IP头部包括
IP地址
,为IP模块使用,MAC头部包括MAC地址,为数据链路层使用。 - 10、
IP模块
会把整个消息包交给网络硬件,也就是数据链路层,比如以太网,WIFI等 - 11、然后网卡会将这些包转换成
电信号或者在光信号
,通过网线或者光纤发送出去,再由路由器等转发设备送达接收方。
服务器端:
- 1、数据包到达服务器的
数据链路层
,比如以太网,然后会将其转换为数据包(数字信号)交给IP模块
。 - 2、
IP模块
会将MAC头部和IP头部后面的内容,也就是TCP数据包发送给TCP模块。 - 3、
TCP模块
会解析TCP头信息,然后和客户端沟通表示收到这个数据包了。 - 4、
TCP模块
在收到消息的所有数据包之后,就会封装好消息,生成相应报文发给应用层,也就是HTTP层。 - 5、
HTTP层
收到消息,比如是HTML数据,就会解析这个HTML数据,最终绘制到浏览器页面上。
TCP连接过程,三次握手和四次挥手,为什么?
连接阶段(三次握手):
- 创建套接字
Socket
,服务器会在启动的时候就创建好,客户端是在需要访问服务器的时候创建套接字 - 然后发起连接操作,其实就是Socket的
connect
方法 - 这时候客户端会生成一个TCP数据包。这个数据包的TCP头部有三个重要信息:
SYN、SEQ、ACK
。
SYN,同步序列编号,是TCP/IP建立连接时使用的握手信号,如果这个值为1就代表是连接消息。
SEQ,数据包序号,是发送数据的一个顺序编号。
ACK,确认号,是接收数据的一个顺序编号。
- 所以客户端就生成了这样一个数据包,其中头部信息的
SYN
设置为1,代表连接。SEQ
设置一个随机数,代表初始序号,比如100。ACK
没有设置,因为是第一次发送数据,不需要ACK
。 - 然后服务器端收到这个消息,知道了客户端是要来连接的
(SYN=1)
,知道了传输数据的初始序号(SEQ=100)
。 - 服务器端也要生成一个数据包发送给客户端,这个数据包的TCP头部会包含
三个值
:表示我也要连接你的SYN(SYN=1)
,我已经收到了你的上个数据包的确认号ACK(ACK=SEQ+1=101)
,以及服务器端随机生成的一个序号SEQ(比如SEQ=200)
。 - 最后客户端收到这个消息后,表示客户端到服务器的连接是无误了,然后再发送一个数据包表示也确认收到了服务器发来的数据包,这个数据包的头部就主要就是一个
ACK值(ACK=SEQ+1=201)
。 - 至此,连接成功,三次握手结束,后面数据就会正常传输,并且每次都要带上TCP头部中的
SEQ和ACK值
。
这里有个问题是关于为什么需要三次握手
?
最主要的原因就是需要通信双方都确认自己的消息被准确传达过去了。
A发送消息给B,B回一条消息表示我收到了,这个过程就保证了A的通信能力。B发送消息给A,A回一条消息表示我收到了,这个过程就保证了B的通信能力。
也就是四条消息能保证双方的消息发送都是正常的,其中B回消息和B发消息,可以融合为一次消息,所以就有了三次握手
。
数据传输阶段:
数据传输阶段有个改变就是ACK确认号
不再是SEQ+1
了,而是SEQ+数据长度
。例如:
- A发送给B的数据包(SEQ=100,长度=1000字节)
- B回给A的数据包(ACK=100+1000=1100)
这就是一次数据传输的头部信息,ACK
代表下个数据包应该从哪个字节开始所以等于上个数据包的SEQ+长度,SEQ就等于上个数据包的ACK。
当然,TCP通信是双向的,所以实际数据每个消息都会有SEQ和ACK
:
- A发送给B的数据包(ACK=200,SEQ=100,长度=1000字节)
- B回给A的数据包(ACK=100+1000=1100,SEQ=上一个数据包的ACK=200,长度=500字节)
- A发送给B数据包(SEQ=1100,ACK=200+500=700)
断开阶段(四次挥手):
和连接阶段一样,TCP头部也有一个专门用作关闭连接的值叫做FIN。
- 客户端准备关闭连接,会发送一个
TCP数据包
,头部信息中包括(FIN=1代表要断开连接)
。 - 服务器端收到消息,回复一个数据包给客户端,头部信息中包括
ACK确认号
。但是此时服务器端的正常业务可能没有完成,还要处理下数据,收个尾。 - 客户端收到消息。
- 服务器继续处理数据。
- 服务器处理数据完毕,准备关闭连接,会发送一个
TCP数据包
给客户端,头部信息中包括(FIN=1代表要断开连接) - 客户端端收到消息,回复一个数据包给服务器端,头部信息中包括
ACK确认号
。 - 服务器收到消息,到此服务器端完成连接关闭工作。
- 客户端经过一段时间(2MSL),自动进入
关闭状态
,到此客户端完成连接关闭工作。
MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
这里有个问题是关于为什么需要四次挥手?
A发送断开消息给B,B回一条消息表示我收到了,这个过程就保证了A断开成功。B发送断开消息给A,A回一条消息表示我收到了,这个过程就保证了B断开成功。
其实和连接阶段的区别就在于,这里的B的确认消息和断开消息不能融合
。因为A要断开的时候,B可能还有数据要处理要发送,所以要等正常业务处理完,在发送断开消息。
常用的状态码
1XX
- 临时消息。服务器收到请求,需要请求者继续操作。2XX
- 请求成功。请求成功收到,理解并处理。3XX
- 重定向。需要进一步的操作以完成请求。4XX
- 客户端错误。请求包含语法错误或无法完成请求。5XX
- 服务器错误。服务器在处理请求的过程中发生了错误。
常见状态码:
200 OK
- 客户端请求成功301
- 资源(网页等)被永久转移到其它URL302
- 临时跳转400 Bad Request
- 客户端请求有语法错误,不能被服务器所理解404 - 请求资源不存在
,错误的URL。500
- 服务器内部发生了不可预期的错误。503 Server Unavailable
- 服务器当前不能处理客户端的请求,一段时间后可能恢复正常。
讲一下TCP协议和UDP协议的区别和场景
我先说两个场景,大家可能就比较能理解了。
1) 第一个场景,浏览网页
。(TCP场景)
- 我们访问网页,网页肯定要把所有数据都正确的显示出来吧,如果这个过程中丢包了,那么肯定也会重新传包,不可能只显示一部分网页(保证数据正确性)
- 同样,网页中的内容肯定也需要是
顺序
的。比如我一个抽奖,不可能还没抽就把奖给你了。(保证数据的顺序) - 再来,在这个对数据要求严格的过程中,我们肯定需要两方建立起一个
可靠
的连接,也就是我们上述说到的要经过三次握手才开始传输数据,并且每次发数据包都需要回执(面向连接的) - 而这种连接中传输数据就是用的
字节流
,也就是有根管道,你想怎么传数据都行,想怎么接受数据也都可以,只要在这一根管道里面。
所以这种需要数据准确、顺序不能错、要求稳定可靠
的场景就需要用到TCP。
2)第二个场景,打游戏。(UDP场景)
打游戏最最重要的就是即时,不然我这个技能发出去了你那边还没被打中,这就玩不了了。
- 所以
UDP
是需要保证数据的即时性
,而不保证每个数据包都正确接收到,即使丢包了,也不会去找丢的那个是什么包,因为要显示当前时间的当前数据包。(不保证数据正确性和数据顺序,可能会丢包) - 同样,为了数据的即时性,
UDP
也就不会去建立连接了,不需要什么三次握手,每次你还要确认收没收到。管你收没收到,我只要快速把每个数据包丢给你就行了。(面向无连接的) - 因为是
无连接
的,所以就不需要用到字节流,直接每次丢一个数据报
给你,接收方也只能接受一个数据报(不能和其他发送方的数据报混淆)。(基于数据报的)
如果你还是有点晕,可以看看这篇文章(亚当和夏娃),很形象的比喻:https://www.zhihu.com/question/51388497?sort=created
socket和WebSocket
虽然这两个货名字类似,但其实不是一个层级的概念。
socket
,套接字。上文说过了,在TCP建立连接的过程中,是调用了Socket的相关API,建立了这个连接通道。所以它只是一个接口,一个类。WebSocket
,是和HTTP同等级,属于应用层协议。它是为了解决长时间通信的问题,由HTML5规范引出,是一种建立在TCP协议基础上的全双工通信的协议,同样下层也需要TCP建立连接,所以也需要socket。
科普:WebSocket在TCP连接建立后,还要通过Http进行一次握手,也就是通过Http发送一条GET请求消息给服务器,告诉服务器我要建立WebSocket连接了,你准备好哦,具体做法就是在头部信息中添加相关参数。然后服务器响应我知道了,并且将连接协议改成WebSocket,开始建立长连接。
如果硬要说这两者有关系,那就是WebSocket
协议也用到了TCP连接
,而TCP连接用到了Socket
的API。