计算机网络
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP设有一个保活计时器,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
为什么TCP连接的时候是3次?2次不可以吗?
为了防止 已失效的链接请求报文突然又传送到了服务端,因而产生错误。客户端发出的连接请求报文并未丢失,而是在某个网络节点长时间滞留了,以致延误到链接释放以后的某个时间才到达Server。这是,Server误以为这是Client发出的一个新的链接请求,于是就向客户端发送确认数据包,同意建立链接。若不采用“三次握手”,那么只要Server发出确认数据包,新的链接就建立了。由于client此时并未发出建立链接的请求,所以其不会理睬Server的确认,也不与Server通信;而这时Server一直在等待Client的请求,这样Server就白白浪费了一定的资源。若采用“三次握手”,在这种情况下,由于Server端没有收到来自客户端的确认,则就会知道Client并没有要求建立请求,就不会建立链接。
为什么客户端发出第四次挥手的确认报文后要等2MSL的时间才能释放TCP连接?
保证最后一次挥手的报文能够到达服务器,若第四次挥手的报文段丢失了,服务器会超时重传第三次的挥手报文段。等待2MSL是为了确保服务器端能收到客户端的回应。
如果客户端直接CLOSED,如果又发起一个连接,有可能网络中还存在上一次连接的数据, 等待2MSL是为了让网络中上一次连接的数据都消失。
什么是Token
Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位
session与token区别
- session机制存在服务器压力增大,CSRF跨站伪造请求攻击,扩展性不强等问题;
- session存储在服务器端,token存储在客户端
- token提供认证和授权功能,作为身份认证,token安全性比session好;
- session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上,token适用于项目级的前后端分离(前后端代码运行在不同的服务器下)
TCP 协议如何保证可靠传输
- 应用数据被分割成 TCP 认为最适合发送的数据块。
- TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
- 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
- TCP 的接收端会丢弃重复的数据。
- 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
- 拥塞控制: 当网络拥塞时,减少数据的发送。
- 停止等待协议 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
在浏览器中输入url地址 ->> 显示主页的过程
TCP流量控制
流量控制:控制发送者的发送速度,使得接收者来得及接收,达到不丢失分组的目的。流量控制是构成TCP可靠性的一方面,主要使用滑动窗口来实现
主机A向主机B发送数据,开始双方确定的窗口值为400字节,这两个是前提条件。开始A发送了200字节,之后发生了分组丢失现象,B调整接受窗口大小为300字节。之后A又连续发送了300字节。此时A已经不能发送数据,需等待B的窗口信号。之后B调整窗口为100字节。接收到100字节数据后,调整窗口值为0,表示暂时不想接受数据。总共B调整了三次窗口大小,进行了三次流量控制
假如,B向A发送了零窗口的报文段后不久,B的接收缓存又有了一些存储空间。于是B向A发送了rwind=400的报文段,然而这个报文段在传送中丢失 了。A一直等待收到B发送的非零窗口的通知,而B也一直等待A发送的数据。这样就死锁了。为了解决这种死锁状态,TCP为每个连接设有一个持续计时器。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器,若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。
TCP拥塞控制
拥塞:在某段时间,对网络中的某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变化,这种情况叫拥塞
拥塞控制:防止过多的数据注入到网络,导致网络中的路由器或链路过载。
流量控制和拥塞控制的区别:流量控制是一个端到端的问题,拥塞控制是一个全局性的问题,设计到网络内的所有主机和路由器
慢开始
发送方维持一个拥塞窗口cwnd,大小取决于网络的拥塞程度,动态地在变化。发送窗口小于等于拥塞窗口,而发送窗口一定不能超过接收窗口。发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就增大一些,以便把更多的分组发送出去。但是只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络的分组数。
开始时,如果发送大量数据包,容易导致网络中路由器缓冲空间耗尽,从而发生拥塞。所以新建连接时,cwnd初始化为1个最大报文段(MSS)大小,每经过一个迭代,拥塞窗口就乘以2,所以也称为乘法增加阶段。拥塞窗口不可能一直增大,所以一般会设置一个慢开始门限ssthresh
- 当cwnd<ssthresh时,使用慢开始算法。
- 当cwnd>ssthresh时,改用拥塞避免算法。
拥塞避免
一旦cwnd达到慢开始门ssthresh,就进入拥塞避免的阶段,此时cwnd每次只增加1,并不是一倍。
快重传
快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。快重传策略是为了防止TCP连接因等待重传计时器超时而空闲较长的时间。
快恢复
快重传和快恢复是搭配使用的,快重传完成后,立即执行快恢复算法。将ssthresh门限设置为当前拥塞窗口的一半,之后将拥塞窗口设置为新的ssthresh门限(即减半), 进入拥塞避免阶段。
为什么不直接进入慢开始阶段而是直接进入拥塞控制阶段,是因为如果网络出现拥塞的话,就不会收到多次的重复确认,所以发送方可能认为网络没有问题,所以不执行慢开始算法,而是将cwnd设置为ssthresh,执行拥塞控制
TCP的no_delay
Nagle算法:把较小的包组装成更大的帧用来解决网络拥塞问题
使用场景:我们假设应用程序发出一个请求,希望发送小块数据,比如一些确认按钮,我们有立即发送和等待产生更多的数据后打包发送两种策略,在更看交互性的应用程序中,立即发送显然更好,此时可以使用 套接字中的TCP_NODELAY来完成,禁用Nagle算法。如果需要等到数据量大了一次性发送,则使用TCP_CORK来使用Nagle算法。
HTTP状态码
100:continue
101: 升级协议
200:ok
201:资源创建成功,多用于POST
204:响应不会返回body
206:当请求多媒体数据过大的时候,数据会进行分片传输
301:永久重定向
302:临时重定向,在重定向的时候会改变method,把POST改成GET
304:资源已经被缓存
307:临时重定向,在重定向的时候不会改变method
400:服务器无法理解参数
401:没有权限
403:拒绝访问
404:未找到资源
405:请求method错误
413:请求的body过大
429:请求过多被限流
500:服务器内部错误
503:服务不可用
504:网关超时,上游应用层未响应
DNS用的是TCP还是UDP
DNS占用53端口,同时使用TCP和UDP
TCP 连接中怎么判断对面断开了
使用心跳包来检查,所谓的心跳包就是客户端定时发送简单的信息给服务器告诉它我还在,一般都是很小的包,或者是只包含头部的空包。
TCP粘包
什么是TCP粘包
TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。
原因
(1)发送方原因
TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:
-
只有上一个分组得到确认,才会发送下一个分组
-
收集多个小分组,在一个确认到来时一起发送
Nagle算法造成了发送方可能会出现粘包问题
(2)接收方原因
TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。**这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包 **
处理
- 发送方关闭Nagle算法,使用TCP_NODELAY选项关闭算法
UDP不会产生粘包问题。
301 永久重定向的返回地址是存在哪里的,具体哪个字段里面?
新的URL定义在响应报文的Location里面,客户端自动用心的URL获取对象。