目录
http和https的区别
- http协议运行在TCP之上,明文传输,客户端与服务端都无法验证对方的身份;https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。
- http和https使用不同的连接方式,用的端口也不一样,http是80,https是443。
- 由于https需要加密解密,会比http通信消耗更多的CPU和内存资源。
- https通信需要证书,而证书一般需要向认证机构购买。
对称加密和非对称加密
- 对称密钥加密指的是加密和解密使用同一个密钥,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方
- 非对称加密指的是使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。“非对称加密”的加密算法,特点是私钥加密后的密文,只要是公钥,都可以解密,但是公钥加密后的密文,只有私钥可以解密。私钥只有一个人有,而公钥可以发给所有的人。 由于不需要发送用来解密的私钥,所以可以保证安全性,但是和对称加密比起来,它非常的慢。
http响应码
- 1xx:信息类
100:信息型状态码目前为止一切正常,客户端应该继续请求,如果已完成请求则忽略。
101:服务器应客户端升级协议的请求,正在进行协议切换 - 2xx:操作成功
200:正确的请求返回正确的结果
201:资源被正确创建
202:请求正确,结果正在处理中
203:这部分信息是缓存,不一定是最新的,需要自己判断处理 - 3xx:重定向
300:请求成功,但结果有多种选择
301:资源被永久性转移,应使用新URI
302:资源暂时性转移,应继续使用原有URI
304:用其他策略获取资源 - 4xx:请求错误
400:地址不存在或包含不支持的参数
401:未授权或认证失败
403:没有权限
404:请求的资源不存在
408:请求超时 - 5xx:服务器错误
500:服务器内部错误
501:请求还没有被实现
502:网关错误
503:服务暂时不可用。服务器维护中或超载
505:请求的http版本不支持
转发和重定向
- forward(转发):服务端接收请求后,替浏览器向另一个URL发送请求,因此浏览器只发送了一次请求。地址栏在转发后不改变。
- redirect(重定向):服务端接收第一次请求后,让浏览器向另一个URL再发送请求,因此浏览器发送了两次请求。地址栏在重定向之后会发生改变。
TCP和UDP区别
TCP:传输控制协议
UDP:用户数据报协议
- TCP数据传输的单位是报文段;UDP数据传输的单位是用户数据报。
- TCP面向连接,需要三次握手才能建立连接;UDP是无连接的,即发送数据之前不需要建立连接。
- TCP提供可靠的服务,通过TCP传送的数据,无差错、不丢失、不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。
- UDP的工作效率比TCP高,适用于对高速传输和实时性有较高要求的通信。
- 每一条TCP连接只能是点到点的;UDP支持一对一、多对多、多对一、多对多的交互通信
- TCP对系统资源要求较多,UDP对系统资源要求较少。
TCP协议如何来保证传输的可靠性
- 数据包校验:检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出任何响应,这时TCP发送数据端超时后会重发数据。
- 对失序数据包重排序:既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对失序数据进行重新排序,然后才交给应用层。
- 丢弃重复数据:对于重复数据,能够丢弃。
- 应答机制:当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒。
- 超时重发:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
- 流量控制:TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能容纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。
TCP的三次握手和四次挥手
ACK、SYN、FIN、seq、ack
大写的就是标志位,小写的就是序号
- 序列号
seq
:占4个字节,是这个报文段中的第一个字节的数据编号。 - 确认号
ack
:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号。 - 确认
ACK
:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效 - 同步
SYN
:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。 - 终止
FIN
:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
三次握手
四次挥手
常见问题
- 为什么不是两次或四次握手?
不是两次的原因是为了避免无效的连接请求突然发送到服务端,而此时客户端已关闭,服务端误以为客户端将要发送数据会白白浪费资源。不是四次的原因是理论上无论收发多少次都不能保证完全可靠,三次是保证双方互相明确对方能收能发的最低值。 - 为什么不是三次挥手?
不是三次的原因第一是为了保证客户端发送的最后一个报文可以到达服务端;第二是防止已失效的报文发送到客户端,在2MSL后客户端在本连接时间内发出的所有报文都将从网络中消失。 - 为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。 - 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
我们必须假想网络是不可靠的,最后一个ACK有可能丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。客户端最后发送的ACK回复如果丢失,服务端没有收到ACK,将不断重复发送FIN片段。所以客户端不能立即关闭,它必须确认服务端接收到了该ACK。客户端会在发送出ACK之后进入到TIME_WAIT状态,会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么客户端会重发ACK并再次等待2MSL。
所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,客户端都没有再次收到FIN,就能推断ACK已经被成功接收,则结束TCP连接。
TCP粘包
-
发送方产生粘包
当发送的数据包过于小时,TCP协议会默认启用Nagle算法,将这些较小的数据包进行合并发送;这个合并过程是在缓冲区进行的,就是说数据发送出来时它已经是粘包的状态了。
-
接收方产生粘包
接收方采用TCP协议接收数据的过程是这样的:数据到达接收方,从网络模型的下方传递至传输层,将其放置接收缓冲区,然后由应用层来主动获取。当程序中读取数据的函数不能及时把缓冲区中的数据拿出来,而下一个数据又到来并放入缓冲区末尾,等我们读取到数据时就是一个粘包。(放数据的速度>应用层拿数据的速度)
OSI七层模型
物理层:以太网、光导纤维。物理层上传输的数据单位是比特,用电压的大小表示。(注意,传递信息所用的一些物理媒体,如双绞线、同轴电缆、光缆、无线信道等,并不在物理协议之内而在物理层协议的下面)
数据链路层:WIFI。传输的数据单位是帧,每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错控制等)
网络层:IPV4、IPV6。网络层把运输层产生的报文段或用户数据报封装成分组或包进行传送。网络层传输的是数据报。另一个任务是选择合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由器找到目的主机。
传输层:TCP、UDP。负责向两台主机进程之间的通信提供通用的数据传输服务。
会话层
表示层
应用层:HTTP、SSL、HTTPS、Telnet。通过应用进程间的交互来完成特定网络应用。
get、post的区别
- get请求参数会直接暴露在URL上,所以不能用来传递敏感信息;post的参数放在request body中。
get产生的地址可以被bookmark(就是添加到浏览器收藏夹),参数也会被完整保留在浏览器历史记录里;而post不可以。 - get请求在URL传送的参数中是有长度限制的,而post没有
- get在浏览器回退时是无害的(即使用浏览器缓存,不重新加载);post会再次提交请求
- get请求只能进行url编码;而post支持多种编码方式
对参数的数据类型,get只接受ASCII字符;而post没有限制
如何实现跨域
- 图片ping或script标签跨域
- JSONP跨域
- 是数据格式JSON的一种使用模式,利用
<script>
元素得到其他网域来源动态产生的JSON数据。用JSONP抓到的数据不是JSON,而是JavaScript,用JavaScript解释器运行。 - 实现原理:即 json+padding,动态创建script标签,利用script标签的src属性可以获取任何域下的js脚本,通过这个特性,服务器端返回js代码,在src中进行调用,实现了跨域。
- 是数据格式JSON的一种使用模式,利用