计算机网络

计算机网络

  • OSI七层协议及TCP/IP四层协议
  • 通信交互方式
  • MAC地址和IP地址
  • ARP协议的作用
  • ping发生了什么
  • traceroute发生了什么
  • TCP/UDP的区别和应用场景
  • 拥塞控制和流量控制的区别
  • TCP滑动窗口实现流量控制
  • TCP超时重传
  • TCP拥塞机制
  • TCP三次握手及三次缘由
  • TCP四次挥手及四次缘由
  • TIME-WAIT状态及2MSL时间
  • 域名系统DNS
  • 统一资源定位符URL
  • 描述一下HTTP协议
  • HTTP2.0
  • HTTP持久连接与管线化
  • HTTP协议请求报文具体信息
  • GET和POST的区别
  • HTTP协议响应报文具体信息
  • HTTP状态码
  • 浏览器键入URL后的访问流程
  • IP/TCP/UDP分片
  • 对称密钥和公钥密码体制
  • 数字签名和数字证书
  • HTTP和HTTPS的区别
  • 运输层安全协议及SSL工作过程
  • HTTPS必须在每次请求中都要先在SSL/TLS层进行握手传输密钥吗?
  • cookie和session
  • 浏览器关闭后,session就销毁了吗

IP地址、子网掩码、网关

互联网是由许多小型网络构成的,每个网络上都有许多主机,这样便构成了一个有层次的结构。IP地址在设计时就考虑到地址分配的层次特点,将每个IP地址都分割成网络号和主机号两部分,以便于IP地址的寻址操作。

IP地址的网络号和主机号各是多少位呢?如果不指定,就不知道哪些位是网络号、哪些是主机号,这就需要通过子网掩码来实现。

什么是子网掩码 子网掩码不能单独存在,它必须结合IP地址一起使用。子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。子网掩码的设定必须遵循一定的规则。与IP地址相同,子网掩码的长度也是32位,左边是网络位,用二进制数字“1”表示;右边是主机位,用二进制数字“0”表示。

网关(Gateway)就是一个网络连接到另一个网络的“关口”。 按照不同的分类标准,网关也有很多种。TCP/IP协议里的网关是最常用的,在这里我们所讲的“网关”均指TCP/ IP协议下的网关。

OSI七层协议及TCP/IP四层协议

  • 七层协议:物、数、网、传、会、表、应

    • 物理层 RJ45
    • 数据链路层 PPP,IEEE 802.3/802.2
    • 网络层 IP,ARP
    • 传输层 TCP,UDP
    • 会话层
    • 表示层 TIFF,GIF,JPEG,
    • 应用层 DNS,HTTP,FTP
  • 四层协议:网络接口层(物理层,数据链路层),网络层(网络层),传输层(传输层),应用层(会话层,表示层,应用层)

    • 网络接口层: PPP MAC不属于协议,只是一个地址、ARP、RARP
    • 网络层:IP、ICMP
    • 传输层:TCP、UDP
    • 应用层:DNS、HTTP、FTP
  • 不同的协议层对数据包有不同的称谓,在传输层叫,在网络层叫数据报,在链路层叫

通信交互方式

  • 单工通信
    • 只能有一个方向的通信没有反方向的交互
  • 半双工通信
    • 双方可以发送消息,但不能同时发送。可以交替进行一方发送、另一方接收
  • 全双工通信
    • 通信的双方可以同时发送和接收信息

MAC地址和IP地址

  • MAC地址又叫硬件地址或物理地址,它不是地址位置,实际上是适配器地址,每一台计算机中固化在适配器的ROM中的地址,作用是用来定义网络设备的位置,MAC地址的长度为48位bit(6个字节),通常表示为12个16进制数。
  • IP地址是IP协议提供的一种统一的地址格式,为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异
  • 两者的区别
    • 物理地址是数据链路层和物理层使用的地址,放在MAC帧的首部
    • IP地址是网络层和以上各层使用的地址,放在IP数据报的首部

MAC地址表、ARP缓存表、路由表

MAC地址表

说到MAC地址表,就不得不说一下交换机的工作原理了,因为交换机是根据MAC地址表转发数据帧的。在交换机中有一张记录着局域网主机MAC地址与交换机接口的对应关系的表,交换机就是根据这张表负责将数据帧传输到指定的主机上的。

交换机在接收到数据帧以后,首先、会记录数据帧中的源MAC地址和对应的接口到MAC表中,接着,会检查自己的MAC表中是否有数据帧中目标MAC地址的信息,如果有则会根据MAC表中记录的对应接口将数据帧发送出去(也就是单播),如果没有,则会将该数据帧从非接收接口发送出去(也就是广播)。

1.主机A -----> 交换机 -----> 主机B

  • 主机A会将一个源MAC地址为自己目标MAC地址为主机B(如何得到主机B的MAC地址下面再讲)的数据帧发送给交换机;
  • 交换机收到该数据帧之后,首先将数据帧中的源MAC地址与对应的接收接口记录到MAC地址表中;
  • 然后交换机会检查自己的MAC地址表中是否有目标MAC地址的信息,如果有,则从MAC地址表中记录的接口发送数据帧;如果没有,则将数据帧从非接收的所有其他接口发送出去(广播);
  • 这时,局域网内的所有主机都会收到数据帧,但是只有主机B收到此数据帧时会响应这个广播,并回应一个数据帧,此数据帧中包括主机B的MAC地址;
  • 交换机收到主机B回应的数据帧后,会将主机B的MAC地址与对应的接口记录到MAC地址表中,这时,再当主机A和主机B通信时,交换机就可以根据MAC地址表中的记录,实现单播了。

2.主机A/主机B -----> 交换机1 -----> 交换机2 -----> 主机C

  • 主机A会将一个源MAC地址为自己目标MAC地址为主机C的数据帧发送给交换机1;
  • 交换机1收到该数据帧之后,会学习源MAC地址,并检查MAC地址表,发现没有目标MAC地址的记录,那么会将数据帧从所有非接收接口广播出去;
  • 主机B和交换机2都会收到该数据帧,交换机2收到此数据帧后也会将数据帧中的源MAC地址和对应的接口记录到MAC地址表中,并检查自己的MAC地址表,发现没有目标MAC地址的记录,则会广播此数据帧。
  • 主机C收到数据帧之后,会响应这个广播,并回复一个源MAC地址为自己的数据帧,这时交换机1和交换机2都会将主机C记录到自己的MAC地址表中,并以单播的形式将数据帧发送给主机A;
  • 这时,主机A和主机C通信就是一单播的形式传输数据帧了,主机B和主机C通信如上述过程一样,因此交换机2的MAC地址表中记录着主机A和主机B的MAC地址对应于同一接口。

==注意:==交换机具有动态学习源MAC地址的功能,并且交换机的一个接口可以对应多个MAC地址,但是一个MAC地址只能对应一个接口。交换机动态学习的MAC地址默认只有300S的有效期,如果300S内记录的MAC地址没有通信,则会删除此记录。

ARP缓存表

上面我们讲解了交换机的工作原理,知道交换机是通过MAC地址通信的,但是我们是如何获得目标主机的MAC地址呢?这时我们就需要使用ARP协议了,在每台主机中都有一张ARP表,它记录着主机的IP地址和MAC地址的对应关系。

  • 如果主机A想发送数据给主机B,主机A首先会检查自己的ARP缓存表,查看是否有主机B的IP地址和MAC地址的对应关系,如果有,则会将主机B的MAC地址作为源MAC地址封装到数据帧中。如果没有,主机A则会发送一个ARP请求信息,请求的目标IP地址是主机B的IP地址,目标MAC地址是MAC地址的广播帧(即FF-FF-FF-FF-FF-FF),源IP地址和MAC地址是主机A的IP地址和MAC地址。
  • 当交换机接受到此数据帧之后,发现此数据帧是广播帧,因此,会将此数据帧从非接收的所有接口发送出去。
  • 当主机B接受到此数据帧后,会校对IP地址是否是自己的,并将主机A的IP地址和MAC地址的对应关系记录到自己的ARP缓存表中,同时会发送一个ARP应答,其中包括自己的MAC地址。
  • 主机A在收到这个回应的数据帧之后,在自己的ARP缓存表中记录主机B的IP地址和MAC地址的对应关系。而此时交换机已经学习到了主机A和主机B的MAC地址了。

windows/linux下可以通过命令行中输入"arp -a"查看本机的ARP缓存表。

路由表

路由器负责不同网络之间的通信,它是当今网络中的重要设备,可以说没有路由器就没有当今的互联网。在路由器中也有一张表,这张表叫路由表,记录着到不同网段的信息。

  • 主机A在网络层将来自上层的报文封装成IP数据包,其中源IP地址为自己,目标IP地址是主机B,主机A会用本机配置的32位子网掩码与目标地址进行“与”运算,得出目标地址与本机不是同一网段,因此发送主机B的数据包需要经过网关路由A的转发。
  • 主机A通过ARP请求获取网关路由A的E0口的MAC地址,并在链路层将路由器E0接口的MAC地址封装成目标MAC地址,源MAC地址是自己。
  • 路由器A从E0口接收到数据帧,把数据链路层的封装去掉,并检查路由表中是否有目标IP地址网段(即192.168.2.2的网段)相匹配的的项,根据路由表中记录到192.168.2.0网段的数据请发送给下一跳地址10.1.1.2,因此数据在路由器A的E1口重新封装,此时,源MAC地址是路由器A的E1接口的MAC地址,封装的目标MAC地址则是路由器B的E1接口的MAC地址。
  • 路由B从E1口接收到数据帧,同样会把数据链路层的封装去掉,对目标IP地址进行检测,并与路由表进行匹配,此时发现目标地址的网段正好是自己E0口的直连网段,路由器B通过ARP广播,获知主机B的MAC地址,此时数据包在路由器B的E0接口再次封装,源MAC地址是路由器B的E0接口的MAC地址,目标MAC地址是主机B的MAC地址。封装完成后直接从路由器的E0接口发送给主机B。
  • 此时主机B才会收到来自主机A发送的数据。

cmd中,输入route print -4查看ipv4路由表

linux主机上,使用route -n 查看当前路由表

总结:路由表负责记录一个网络到另一个网络的路径,因此路由器是根据路由表工作的。

以太网数据包转发流程是这样的

假如主机A向主机B通信,主机A需要得到主机B的MAC地址,首先主机A会利用子网掩码的与操作来判断主机B与自己是否在同一网段,如果在同一网段,就会使用ARP协议到ARP缓存表中去查询主机B的MAC地址(流程就是上述ARP缓存表的流程);如果不在同一网段,主机A会查询路由表看有没有能到达B主机所在网络的具体路由,如果找不到,就找到默认网关的IP地址,将默认网关作为自己的下一跳,但是还需要得到默认网关的MAC地址(即F0/0)接口的MAC地址;这时主机A会通过ARP请求来找到网关的MAC地址,然后将数据帧的目的MAC地址设置为路由器的F0/0接口,目的IP地址仍然是主机B的IP地址,并将数据帧转发到网关;到了路由器之后,路由器如何知道下一步要往哪发送呢?当路由器从F0/0接口接收到数据帧后,就会按照上述路由表流程来查询接下来的转发路径。(要注意,如果在路由器的路由表里找到多个匹配的路由项,路由查找进程会选择其中掩码最长的路由项进行转发,掩码越长表明代表的网络范围越小,匹配的程度就越精确。这就是所谓的最长匹配原则。如果找不到路由项,则丢弃该IP报文。但是如果在路由表中有缺省路由存在,则路由器将按照缺省路由来转发IP报文。缺省路由又称为默认路由,其目的地址和子网掩码均为0.0.0.0。)

ARP协议的作用

网络层使用的是IP地址,数据链路层使用的是硬件地址。
ARP协议的用途是为了从网络层使用的IP地址,解析出数据链路层使用的硬件地址。

  • 在主机ARP高速缓存中存放一个从IP地址到硬件地址的映射表
  • 当需要解析时,先去arp缓存表(存着ip-mac对应关系)去查找目标ip的mac地址
  • 如果查到了,将目标ip的mac地址封装到链路层数据报
  • 如果缓存中没有找到,会发起一个广播:who is ip XXX tell ip XXX,所有收到的广播的机器看这个ip是不是自己的,如果是自己的,则以单播的形式将自己的mac地址回复给请求的机器

ARP攻击

  • 当主机A和主机B通信时,主机A查询ARP缓存表未命中时,此时就会广播,网段内的所有主机都会收到这个广播帧,不是主机B的主机验证后会丢弃掉这个广播帧,只有主机B验证后会回发一个单播。然后此时交换机的ARP缓存表中就会记录主机B的ip和mac地址。
  • 但是额外的主机C是可以利用这一环节的漏洞的,当主机C收到这个不属于自己广播包时,它并不会丢弃,而是响应一个虚假的回应包,告诉主机A,我就是主机B。
  • 因为主机B也会响应这个广播帧,所以此时主机A收到了两个回应包,它并不知道到底哪个是真的,所以主机A会作出判断,并且判断后到达的为真,那怎恶魔让虚假的回应包后到达呢,主机C可以连续不断地发送这样的回应包,总会把那个正确的回应包覆盖掉。
  • 此时主机A就会建立一个主机B地ip对应主机C地mac地址地映射,以后当主机A给主机B发送数据地时候,就会把数据发给主机C,完成一次ARP攻击。
  • 如果ARP攻击严重地话,会导致同一个网段地所有主机地ARP缓存表中都存放着错误地ip和mac地映射,这样该网段内地所有主机地消息都发送给了攻击的主机。

ARP攻击发现

判断是否为ARP病毒攻击

  • 当发现上网明显变慢,或者突然掉线时,我们可以用arp -a命令来检查ARP表,如果发现网关的MAC地址发生了改变,或者发现有很多IP指向同一个物理地址,那么肯定就是ARP欺骗所致。这时可以通过”arp -d“清除arp列表,重新访问。
  • 利用ARP防火墙类软件

ARP攻击防护

  • 静态ARP缓存表:每台主机都有一个暂时寄存IP-MAC的对应表ARP攻击就经过更改这个缓存来到达诈骗的意图,运用静态的ARP来绑定正确的MAC是一个有用的办法,在命令行下运用arp -a能够检查当时的ARP缓存表。
  • 自动查询:在某个正常的时间,做一个IP和MAC对应的数据库,以后定时检查当时的IP和MAC对应联系是否正常,定时检查交流机的流量列表,检查丢包率。
  • 使用防护软件

ping发生了什么

ping主要是为了测试两台主机之间的连通性,通过应用层直接使用网络层ICMP,没有通过运输层TCP和UDP,是通过发送ICMP报文回显请求实现。

  • A主机构建一个ICMP格式的数据包,通过ICMP协议把该数据包和B主机的IP地址一起交给IP协议;
  • IP层构建一个数据包(A主机的IP地址+控制信息+B主机的IP地址),并获得B主机的MAC地址,以便构建一个数据帧(IP协议会根据B主机的IP地址和自己的子网掩码判断是不是属于同一层网络,如果是属于同一层网络的话,就能通过ARP协议获得B主机的MAC地址,如果不在同一个网络,那就会先将数据包发送给网关,再由网关来决定发送到哪)
  • 主机B接受到主机A的发过来的数据帧以后,先检查该帧中包含的B的IP地址,并和本地的物理地址进行比对,如果符合的话,就接受,否则,就抛弃。同样,需要将该数据帧交由自己的IP层协议,IP层检查以后,再交由ICMP协议,构建一个ICMP的应答包,发送给主机A。

ping不通的原因有很多:

  • 对方关机
  • 目标ip不存在
  • 位于不同网段,且路由器在路由表中无法找到
  • 防火墙设置导致过滤了ping发出的ICMP数据包
  • 网线故障

traceroute发生了什么

traceroute用来跟踪一个分组从源点到终点的路径,及到达其中每一个路由器的往返时间

  • 通过发送UDP报文,设置目的端口为一个不可能的值
  • 将IP首部中的TTL分别设置从1到N,每次逐个增加
  • 每次设置TTL后,重新发送数据报,路由器接收到数据报后,将TTL减1,若当前的路由器接收到数据报,发现TTL为1时,会将TTL减1变为0,然后丢弃数据报,发送ICMP时间超过报文
  • 如果最后一个数据报刚刚达到主机,数据报的TTL是1,此时主机不把TTL减1
  • 因IP数据报中封装的是无法交付的UDP数据报,此时目的主机向源主机发送ICMP终点不可达差错报文,表示达到目的主机

TCP/UDP

TCP报文首部格式

  • 32位序号seq:一次TCP通信过程中某一个传输方向上的字节流的每个字节的编号。假设主机A和主机B进行通信,A发送给B的第一个TCP报文段中,序号被系统初始化位某个随机值ISN。那么在该传输方向上,后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。
  • 32位确认号ack:用作对另一方发来的TCP报文段的响应,其值是收到的TCP报文段的序号值+1。
  • 4位首部长度:标识该TCP头部有多少个32bit字(4字节),因为4位最多表示15,所以说整个首部最多有4×15 = 60个字节,除去固定的20个字节,还有40个字节,也就是说可变长度部分最多占40个字节。
  • 6位保留位:为将来定义新的用途保留,现在一般置0
  • URG:标记位表示紧急指针是否有效。
  • ACK:表示确认号ack是否有效,为0确认号就无效,发送通信请求时为0,允许通信后就变为1。
  • PSH:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。
  • RST:表示要求对方重新建立连接。若为1,表示TCP会话出现严重错误,需要释放连接,需重新建立连接才可正常通信,比如点开一个网页,还在加载时,点击×就会中断连接,后面的数据报RST就为1,点击刷新就相当于重新建立连。
  • SYN:表示请求建立连接,发起会话的话SYN就为1,当会话建立后SYN就变为0了。
  • FIN:表示通知对端,本端要关闭连接了,在数据通信结束后,要释放连接,后面的数据报FIN位就为1
  • 16位窗口大小:发送方和接收方都需要发送窗口和接收窗口,双方在建立会话时,会确定各自的窗口大小,以此来协商发送数据包的大小
  • 16位检验和:由发送端填充,接收端对TCP报文执行CRC算法以检验TCP报文段在传输过程中是否损坏。
  • 16位紧急指针:是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。

UDP报文首部格式

计算机网络_第1张图片

  • 16位UDP长度:UDP用户数据报的长度,即首部+数据。
  • 16位UDP校验和:检测UDP用户数据报长度在传输中是否有错,有错就丢弃。

区别

TCP,全称:传输控制协议,面向连接的安全的流式传输协议
UDP,全称:用户数据报协议,面向无连接的不安全的报式传输协议

  • 连接

    • TCP是面向连接的传输层协议,即传输数据之前必须先建立好连接。
    • UDP无连接。
  • 服务对象

    • TCP是点对点的两点间服务,即一条TCP连接只能有两个端点
    • UDP支持一对一,一对多,多对一,多对多的交互通信。
  • 可靠性

    • TCP是可靠交付:无差错,不丢失,不重复,按序到达。
    • UDP是尽最大努力交付,不保证可靠交付。
  • 拥塞控制,流量控制

    • TCP有拥塞控制和流量控制保证数据传输的安全性。
    • UDP没有拥塞控制,网络拥塞不会影响源主机的发送效率。
  • 报文长度

    • TCP是动态报文长度,即TCP报文长度是根据接收方的窗口大小和当前网络拥塞情况决定的,流式传输
    • UDP面向报文,不合并,不拆分,保留上面(应用层)传下来报文的边界,直接传输报文。
  • 首部开销

    • TCP首部开销大,首部20个字节。
    • UDP首部开销小,8字节。(源端口,目的端口,UDP数据报长度,检验和,每个字段两个字节)

应用场景

  • 要求通信数据完整性,则应该选用TCP协议(如文件传输、重要状态的更新,登录数据传输等)
  • 要求通信实时性,使用 UDP 协议(如视频传输,通话,屏幕共享软件)

TCP丢包

  • tcp层有可能丢包,比如型号衰减或者网络阻塞等情况,但是这些情况与应用层无关,并且tcp有重传机制和其他安全性机制保证应用层意义上的包的连续性和完整性,所以从应用层协议的角度来看tcp层是不会丢包的

拥塞控制和流量控制的区别

  • 拥塞控制是防止过多的数据注入到网络中,可以使网络中的路由器或链路不致过载,是一个全局性的过程。
  • 流量控制是点对点通信量的控制,是一个端到端的问题,主要就是抑制发送端发送数据的速率,以便接收端来得及接收

TCP滑动窗口实现流量控制

  • 流量控制是让发送方的发送速率不要太快,要让接收方来得及接收,实现对发送方的流量控制.

  • 滑动窗口出现的原因:在确认应答策略中,对每一个发送的数据段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段,这样做有一个比较大的缺点,就是性能比较差,尤其是数据往返的时间长的时候

  • 滑动窗口以字节为单位,而不是报文

  • (1)接收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK来通知发送端
    (2)窗口大小字段越大,说明网络的吞吐率越高
    (3)窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,即就是说不需要接收端的应答,可以一次连续的发送数据
    (4)操作系统内核为了维护滑动窗口,需要开辟发送缓冲区,来记录当前还有那些数据没有应答,只有确认应答过的数据,才能从缓冲区删掉

    (5)接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端,发送端收到这个值后,就会减慢自己的发送速度
    (6)如果接收端发现自己的缓冲区满了,就会将窗口的大小设置为0,此时发送端将不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端

  • ps:发送缓冲区如果太大,就会有空间开销

TCP超时重传

  • 保证了数据的可靠传输,对于一些出错,丢包等问题TCP设计了超时与重传机制。
  • 基本原理:在发送一个数据之后,就开启一个定时器,并设置RTO,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
  • 不同的网络情况不一样,不可能设置一样的RTO(超时重传时间),实际中RTO是根据网络中的RTT(报文段往返时间)来自适应调整的

TCP拥塞机制

  • 拥塞的标志
    • 超时重传
    • 3次重复的ACK

慢启动,拥塞避免,快恢复,快重传

慢启动和拥塞避免(旧的拥塞避免方法)

发送方维持拥塞窗口cwnd

发送方控制拥塞窗口的原则是:

  • 只要网络没有出现拥塞,拥塞窗口就再增大一些(2倍增长),以便把更多的分组发送出去。

  • 只要网络出现拥塞,拥塞窗口就减小一些,以减少注入网络中的分组数。

  • 流程:初始时设置慢开始门限ssthresh为16,第1次传输窗口大小为1,然后呈指数增长,当增长到16(即慢开始门限ssthresh)后,此时就需要慢增长了,每次窗口大小只增长1直到网络出现拥塞。假如当窗口增长到24时网络出现了拥塞,这时就要设置新的慢开始门限ssthresh了,新值应该是网络开始出现拥塞时窗口大小的1/2,即12。然后,窗口大小重新从1开始增长,增长到慢开始门限ssthresh后,再慢慢增长。

  • 强调:“拥塞避免”并非指完全能够避免了拥塞。利用以上的措施要完全避免网络拥塞还是不可能的。“拥塞避免”是说在拥塞阶段把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。

快重传和快恢复(新的拥塞避免方法)

  • 快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认。这样做可以让发送方及早知道有报文段没有到达接收方

  • 当发送端收到连续三个重复的确认时,就执行“乘法减小”算法,把慢开始门限ssthresh减半,但拥塞窗口cwnd现在不设置为1,而是设置慢开始门限ssthresh减半后的值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。

ACK SYN FIN解释及是否消耗序列号

  • ACK 确认标志位,ACK可以携带数据,若不携带,则不消耗序列号
  • SYN 同步标志位,SYN不能携带数据,必须消耗一个序列号
  • FIN 终止标志位,FIN可以携带数据,必须消耗一个序列号

TCP三次握手及三次缘由

  • 三次握手其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。

  • 进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口建立TCP连接,并同步连接双方的序列号和确认号交换TCP窗口大小信息

为什么TCP三次握手,不能两次或者四次吗?

  • 三次握手是为了防止,客户端的请求报文在网络滞留,客户端超时重传了请求报文,服务端建立连接,传输数据,释放连接之后,服务器又收到了客户端滞留的请求报文,建立连接一直等待客户端发送数据。
  • 服务器对客户端的请求进行回应(第二次握手)后,就会理所当然的认为连接已建立,而如果客户端并没有收到服务器的回应呢?此时,客户端仍认为连接未建立,服务器会对已建立的连接保存必要的资源,如果大量的这种情况,服务器会崩溃。
  • 服务器端给客户端发送同步及确认报文时可以合并,四次会浪费时间

什么是半连接队列?

  • 服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列

  • 当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。

  • 这里在补充一点关于SYN-ACK 重传次数的问题:

    服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。

    注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…

ISN(Initial Sequence Number)是固定的吗?

  • 当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器,每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。

    三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。

三次握手过程中可以携带数据吗?

  • 第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据
  • 假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
  • 对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

如果已经建立了连接,但客户端出现了故障怎么办?

  • 服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

SYN攻击(泛洪攻击)是什么?

  • SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

    检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。

    netstat -n -p TCP | grep SYN_RECV
    

    常见的防御 SYN 攻击的方法有如下几种:

    • 缩短超时(SYN Timeout)时间
    • 增加最大半连接数
    • 过滤网关防护
    • SYN cookies技术

TCP四次挥手及四次缘由

四次报文中服务器端发送给客户端的请求关闭连接报文FIN和ACK也是合并的,相对于三次来说,只是前面多了一次ACK的确认。

为什么TCP四次挥手,不能三次吗?

  • 当客户端确认发送完数据且知道服务器已经接收完了,想要关闭发送数据口(当然确认信号还是可以发),就会发FIN给服务器。
  • 服务器收到客户端发送的FIN,表示收到了,就会发送ACK回复。
  • 但这时候服务器可能还在发送数据,没有想要关闭数据口的意思,所以服务器的FIN与ACK不是同时发送的,而是等到服务器数据发送完了,才会发送FIN给客户端。
  • 客户端收到服务器发来的FIN,知道服务器的数据也发送完了,回复ACK, 客户端等待2MSL以后,没有收到服务器传来的任何消息,知道服务器已经收到自己的ACK了,客户端就关闭链接,服务器也关闭链接(服务器比客户端早关闭)。

TIME-WAIT状态及2MSL时间

  • 四次挥手期间,客户端和服务器端都可主动释放连接,谁主动释放,谁将进入TIME_WAIT状态
  • MSL是最长报文寿命,一般为2分钟,2MSL即4分钟
  • 为什么TIME-WAIT状态必须等待2MSL时间?
    • 保证客户端发送的最后一个ACK报文段能够到达服务端。若B收不到A的ACK报文,则B会超时重传FIN+ACK,A会在2MSL时间内收到重传报文段,然后发送ACK,重新启动2MSL计时器
    • 防止“已失效的连接请求报文段”出现在本连接中。2MSL后,本次连接的所有报文都会消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

TIME_WAIT存在的原因

  • 如果服务器最后发送的ACK因为某种原因丢失了,那么客户一定会重新发送FIN,这样因为有TIME_WAIT的存在,服务器会重新发送ACK给客户,如果没有TIME_WAIT,那么无论客户有没有收到ACK,服务器都已经关掉连接了,此时客户重新发送FIN,服务器将不会发送ACK,而是RST,从而使客户端报错。也就是说,TIME_WAIT有助于可靠地实现TCP全双工连接的终止
  • 如果没有TIME_WAIT,我们可以在最后一个ACK还未到达客户的时候,就建立一个新的连接。那么此时,如果客户收到了这个ACK的话,就乱套了,必须保证这个ACK完全死掉之后,才能建立新的连接。也就是说,TIME_WAIT允许老的重复分节在网络中消逝。

服务器出现大量TIME_WAIT的原因

高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接。这个场景下会出现大量socket处于TIME_WAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。

CLOSE_WAIT出现的原因

客户端异常断开,服务器没有捕捉到异常,从而没有使用close()关闭socket,(调用close后就不再是CLOSE_WAIT状态)。总的来说,就是服务器没有调用或没有及时调用close()。

可能的原因:

  • 程序Bug,接收到FIN信号后没有及时关闭socket,这可能是Netty的Bug,也可能是业务层Bug;

  • 关闭socket不及时:例如I/O线程被意外阻塞,或者I/O线程执行的用户自定义Task比例过高,导致I/O操作处理不及时,链路不能被及时释放。

域名系统DNS

用于将域名转换为IP地址。
DNS解析过程有两种,分别是递归查询和迭代查询。

  • 递归查询
    • 若主机询问的本地域名服务器不知道被查询域名的IP地址,本地域名服务器以DNS客户身份,向其他根域名服务器继续发出查询请求报文(代替该主机继续查询),而不是该主机自己进行下一步查询
  • 迭代查询
    • 当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出IP地址,要么告诉本地域名服务器,应该向哪一个域名服务器进行查询,然后本地域名服务器进行后续查询

DNS域名解析过程

计算机网络_第2张图片

  • 浏览器先检查自身缓存中有没有被解析过的这个域名对应的ip地址,如果有,解析结束。
  • 如果浏览器缓存中命中,浏览器会检查操作系统缓存中有没有对应的已解析过的结果。而操作系统也有一个域名解析的过程。在windows中可通过c盘里一个叫hosts的文件来设置,如果你在这里指定了一个域名对应的ip地址,那浏览器会首先使用这个ip地址。但是这种操作系统级别的域名解析规程也被很多黑客利用,通过修改你的hosts文件里的内容把特定的域名解析到他指定的ip地址上,造成所谓的域名劫持。所以在windows7中将hosts文件设置成了readonly,防止被恶意篡改。
  • 如果至此还没有命中域名,才会真正的请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。
  • 如果LDNS仍然没有命中,就直接跳到Root Server 根域名服务器请求解析。
  • 根域名服务器返回给LDNS一个所查询域的顶级域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org等)地址。
  • 此时LDNS再发送请求给上一步返回的gTLD。
  • 接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器。
  • Name Server根据映射关系表找到目标ip,返回给LDNS。
  • LDNS缓存这个域名和对应的ip。
  • LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束。

发现域名打不开怎么办

  1. 先判断网络是否畅通
  2. ping域名,如果没有IP表示域名错误或者域名未作解析,如果超时表示服务器有问题
  3. 如果域名解析有问题就要判断是不是DNS故障,使用nslookup命令,如果出现超时表明DNS出现问题

统一资源定位符URL

统一资源定位符URL,用来表示从互联网上得到的资源位置。

  • 一般由四个部分组成

    • <协议>://<主机>:<端口>/<路径>
    • 主机一般为域名,需要通过DNS系统解析出IP
  • 使用HTTP的URL

    • http://<主机>:<端口>/<路径>

描述一下HTTP协议

概述

  • HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。
  • HTTP属于应用层协议,基于TCP/IP通信协议来传递数据

特点

  • 灵活
    • HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  • 无连接
    • 无连接的含义是通信双方在交换HTTP报文之前不需要建立HTTP连接
  • 无状态
    • 无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时应答较快。
  • 支持B/S和C/S模式
    • C/S模式:客户机(client)/服务器(server)模式。需要在通讯两端各自部署客户机和服务器来完成数据通信。
    • B/S模式:浏览器(browser)/服务器(server)模式。只需在一端部署服务器,而另一端使用每台PC都默认配置的浏览器即可完成数据的传输。
    • 两者优缺点:
      • C/S 优点:客户端位于目标主机上可以保证性能,将数据缓存至客户端本地,从而提高数据传输效率。而且,一般来说客户端和服务器程序由一个开发团队创作,所以他们之间所采用的协议相对灵活。因此传统的网络应用程序以及较大型的网络应用程序都首选C/S模式进行开发,比如大型游戏,3D画面,数据量较为庞大,使用C/S模式可以提前在本地进行大量数据的缓存处理。
      • C/S 缺点:由于客户端和服务器由一个开发团队来完成开发。工作量将成倍提升,开发周期较长。另外,从用户的角度出发,需要将客户端安装在用户主机上,对用户主机的安全性构成威胁。这也是很多用户不愿意使用C/S模式应用程序的重要原因。
      • B/S 优点:由于它没有独立的客户端,使用标准浏览器作为客户端,其工作开发量小,只需开发服务器端即可。另外由于采用浏览器显示数据,因此移植性非常好,不受平台限制。如早期的偷菜游戏,在各个平台上都可以完美运行。
      • B/S 缺点:由于使用第三方浏览器,因此网络应用支持受限。另外,没有客户端放到对方主机上,缓存数据不尽人意,从而传输数据量受到限制。应用的观感大打折扣。第三,必须与浏览器一样,采用标准http协议进行通信,协议选择不灵活
  • 默认端口80
  • 基于TCP协议

HTTP工作原理

HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。

  • 客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。
  • 服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。

HTTP 请求/响应的步骤

  • 客户端连接到Web服务器
    一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.oakcms.cn。
  • 发送HTTP请求
    通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
  • 服务器接受请求并返回HTTP响应
    Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
  • 释放连接TCP连接
    若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
  • 客户端浏览器解析HTML内容
    客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。

HTTP发展历史

版本号 产生时间 内容 发展现状
HTTP/0.9 1991年 不涉及数据包传输,规定客户端与服务器之间的通信格式,只能GET请求 没有作为正式的标准
HTTP/1.0 1996年 传输内容格式不限制,增加PUT、PATCH、HEAD、OPTIONS、DELETE命令 正式作为标准
HTTP/1.1 1997年 持久连接(长连接)、节约带宽、HOST域、管道机制、分块传输编码 2015年前使用最广泛
HTTP/2 2015年 多路复用、服务器推送、头信息压缩、二进制协议等 逐渐覆盖市场

HTTP2

  • 新的二进制格式(Binary Format)
    • HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
  • 多路复用(MultiPlexing)
    • 即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
    • pipelining在接收response返回时,必须依顺序接收,如果前一个请求遇到了阻塞,后面的请求即使已经处理完毕了,仍然需要等待阻塞的请求处理完毕。这种情况就如图中第三种,第一个请求阻塞后,后面的请求都需要等待,这也就是队头阻塞
  • header压缩
    • 对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小
  • 服务端推送
    • 我的网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了

HTTP持久连接与管线化

HTTP协议首先要和服务器建立TCP连接,这需要三次握手。

  • 请求一个万维网文档的时间

    • 当建立TCP连接的三次握手前两次完成后,即经过一个RTT时间,万维网客户就把HTTP请求报文,作为建立TCP连接的三次握手中的第三次的数据,发送给万维网服务器,服务器收到HTTP请求后,把请求的文档作为响应报文返回给客户。
    • 文档传输时间+2*RTT
  • HTTP1.0非持久连接的缺点

    • 每请求一个文档,需要两倍RTT的开销。服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接,然后重新建立连接发出请求
  • HTTP1.1持久连接

    • 万维网服务器在发送响应后仍然在一段时间内保持这段连接,可以使得同一用户继续在该连接上传送后续请求和响应报文
  • 持久连接的两种工作方式

    • 非管线化
      • 发送请求后需等待并收到回应,才能发送下一个请求
    • 管线化
      • 不用等待响应,直接发送下一个请求,但接收的时候必须按照顺序接收,如果有一个请求阻塞,则接收会全部阻塞

HTTP协议请求报文具体信息

HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据四个部分组成

  • GET

    GET /562f25980001b1b106000338.jpg HTTP/1.1
    Host:img.mukewang.com
    User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64)
    AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
    Accept:image/webp,image/*,*/*;q=0.8
    Referer:http://www.imooc.com/
    Accept-Encoding:gzip, deflate, sdch
    Accept-Language:zh-CN,zh;q=0.8
    空行
    请求数据为空
    
  • POST

    POST / HTTP1.1
    Host:www.wrox.com
    User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
    Content-Type:application/x-www-form-urlencoded
    Content-Length:40
    Connection: Keep-Alive
    空行
    name=Professional%20Ajax&publisher=Wiley
    
  • 请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
    GET说明请求类型为GET,/562f25980001b1b106000338.jpg(URL)为要访问的资源,该行的最后一部分说明使用的是HTTP1.1版本。
  • 请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息
    * HOST,给出请求资源所在服务器的域名.
    * User-Agent,HTTP客户端程序的信息,该信息由你发出请求使用的浏览器来定义,并且在每个请求中自动发送等
    * Accept,说明用户代理可处理的媒体类型
    * Accept-Encoding,说明用户代理支持的内容编码
    * Accept-Language,说明用户代理能够处理的自然语言集
    * Content-Type,说明实现主体的媒体类型
    * Content-Length,说明实现主体的大小
    * Connection,连接管理,可以是Keep-Alive或close
  • 空行,请求头部后面的空行是必须的即使第四部分的请求数据为空,也必须有空行。
  • 请求数据也叫主体,可以添加任意的其他数据。

HTTP有哪些方法

  • POST:传输实体主体
  • GET:获取资源
  • PUT:传输文件,存在安全性问题
  • DELETE:删除文件,存在安全性问题
  • HEAD:获取报文头部
  • OPTIONS:询问支持的方法
  • TRACE:追踪路径
  • CONNECT:要求用隧道协议连接代理

POST和PUT的区别

PUT是幂等的方法,POST不是

  • PUT请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源)
  • POST请求:后一个请求不会把第一个请求覆盖掉。(所以POST用来增资源)
  • 幂等的方法有GET、DELETE、PUT,非幂等的方法有POST、PATCH

GET和POST区别

GET /books/?sex=man&name=Professional HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
空行
请求数据为空
  • 区别
    • get参数通过url传递,post放在request body中,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
    • POST的安全性要比GET的安全性高,一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.
    • get请求在url中传递的参数是有长度限制的,而post没有(HTTP协议规范没有限制,特定浏览器及服务器对他的限制)
    • GET产生一个TCP数据包,POST产生两个TCP数据包
      • 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
      • 对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
    • GET请求会被缓存,而POST不会,除非手动设置。
      • GET多用于直接获取数据,不修改数据,主要目的就是database中的search语句的感觉。用缓存的目的就是查db的速度变快;
      • POST则是发送数据到服务端去存储,类似于database中的update和insert语句的感觉,数据必须放在数据库,所以一般都得去访问服务器端,而极少需要缓存;
    • GET请求支持收藏为书签,POST不支持
    • 编码方式:GET请求只能进行url编码,而POST支持多种编码方式
    • 对参数的数据类型:GET只接受ASCII字符,而POST没有限制。
    • 历史记录:GET请求参数会被完整保留在浏览历史记录里,而POST中的参数不会被保留。

HTTP协议响应报文具体信息

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8

      
      
            
      

  • 状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。
    第一行为状态行,(HTTP/1.1)表明HTTP版本为1.1版本,状态码为200,状态消息为OK
  • 消息报头,用来说明客户端要使用的一些附加信息
    第二行和第三行为消息报头,Date:生成响应的日期和时间;Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8
  • 空行,消息报头后面的空行是必须的
  • 响应正文,服务器返回给客户端的文本信息。空行后面的html部分为响应正文

HTTP状态码

  • 1xx:指示信息–表示请求已接收,继续处理。
  • 2xx:成功–表示请求正常处理完毕。
    • 200 OK:客户端请求被正常处理
    • 206 Partial content:客户端进行了范围请求
  • 3xx:重定向–要完成请求必须进行更进一步的操作。
    • 301 Moved Permanently:永久重定向,该资源已被永久移动到新位置,将来任何对该资源的访问都要使用本响应返回的若干个URI之一
    • 302 Found:临时重定向,请求的资源现在临时从不同的URI中获得
    • 304:服务器资源未变化。客户端在请求一个文件的时候,发现自己缓存的文件有 Last Modified(实际上是一个时间) ,那么在请求中会包含 If Modified Since ,这个时间就是缓存文件的 Last Modified 。因此,如果请求中包含 If Modified Since,就说明已经有缓存在客户端。服务端只要判断这个时间和当前请求的文件的修改时间就可以确定是返回 304 还是 200 。Last Modified有两个缺点,一是以s为最小单位进行存储,二是周期性变化,如果一个资源在一个周期内修改位原来的样子,我们认为可以使用缓存,但是Last Modified不这么认为。
  • 4xx:客户端错误–请求有语法错误,服务器无法处理请求。
    • 400 Bad Request:请求报文存在语法错误
    • 403 Forbidden:请求被服务器拒绝
    • 404 Not Found:请求不存在,服务器上找不到请求的资源
  • 5xx:服务器端错误–服务器处理请求出错。
    • 500 Internal Server Error:服务器在执行请求时出现错误
    • 503 Service Unavaliable:服务器正在停机维护

浏览器键入URL后的访问流程

  • 浏览器使用DNS协议向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址,其中DNS服务器是基于UDP的,因此会用到UDP协议;
  • 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接,会使用到TCP协议;
  • 然后浏览器就要与服务器建立一个http连接,因此要用到http协议,http生成一个get请求报文,如果采用https还会使用https协议对http数据进行加密,涉及到SSL协议,将报文发送到TCP层
  • TCP层如果有需要先将HTTP数据包分片,分片依据MTU和MSS( mtu是网络传输最大报文长度,mss是网络传输数据最大值)。
  • TCP的数据包然后会发送给IP层,用到IP协议。IP层通过路由选路,一跳一跳发送到目的地址。
  • 当然在一个网段内的寻址是通过以太网协议实现,以太网协议需要知道目的IP地址的物理地址,则需要ARP协议
  • 服务器端接收到请求,然后发送返回响应请求。
  • 释放 TCP连接(若connection为close,则释放TCP连接,若为keep-alive则不会释放)。
  • 浏览器将该解析html文本并显示内容。

IP/TCP/UDP分片

数据发送时,将数据从应用层->传输层->网络层->数据链路层,其中传输层是TCP和UDP,网络层是IP协议。

  • MTU以太网帧的长度为1500字节,所能接收的传输层数据段最大为 1480 个字节(以太网帧中的数据包括 IP 协议的报头信息,IP 协议的报头信息为 20 字节)

  • 在计算 MSS (网络传输数据最大值)的时候,用 MTU 减去网络层报头长度以及传输层报头长度即可。

  • UDP

    • 一旦 UDP 携带的数据超过了 1472 (MTU - IP报头 - UDP报头 = 1500 - 20 - 8),那么在 IP 层就会对该数据分片,一旦分片就意味着增加了 UDP 传输丢包的可能性。 由于 UDP 协议传输本身就不负责可靠性,再加上分片,那么丢包的可能性就大大增加

    计算机网络_第3张图片

HTTPS加密规则

为什么需要加密

  • 因为http的内容是明文传输的,明文数据会经过中间代理服务器、路由器、wifi热点、通信服务运营商等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了,他还可以篡改传输的信息且不被双方察觉,这就是中间人攻击。所以我们才需要对信息进行加密。最直接的加密方式就是对称加密

什么是对称加密?

  • 就是有一个密钥,它可以对一段内容加密,加密后只能用它才能解密看到原本的内容,和我们日常生活中用的钥匙作用差不多。加密密码和解密密码是相同的密钥。

用对称加密可行吗?

  • 如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。

  • 然而最大的问题就是**这个密钥怎么让传输的双方知晓,同时不被别人知道**。如果由服务器生成一个密钥并传输给浏览器,那这个传输过程中密钥被别人劫持弄到手了怎么办?之后他就能用密钥解开双方传输的任何内容了,所以这么做当然不行。

  • 换种思路?试想一下,如果浏览器内部就预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的,这样浏览器只要预存好世界上所有HTTPS网站的密钥就行啦!这么做显然不现实。
    怎么办?所以我们就需要神奇的非对称加密

什么是非对称加密?

  • 有两把密钥,通常一把叫做公钥、一把叫做私钥,用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。

用非对称加密可行吗?

  • 鉴于非对称加密的机制,我们可能会有这种思路:服务器先把公钥直接明文传输给浏览器,之后浏览器向服务器传数据前都先用这个公钥加密好再传,这条数据的安全似乎可以保障了!因为只有服务器有相应的私钥能解开这条数据
  • 然而由服务器到浏览器的这条路怎么保障安全?如果服务器用它的的私钥加密数据传给浏览器,那么浏览器用公钥可以解密它,而这个公钥是一开始通过明文传输给浏览器的,这个公钥被谁劫持到的话,他也能用该公钥解密服务器传来的信息了。所以目前似乎只能保证由浏览器向服务器传输数据时的安全性(其实仍有漏洞,下文会说),那利用这点你能想到什么解决方案吗?

改良的非对称加密方案,似乎可以?

我们已经理解通过一组公钥私钥,已经可以保证单个方向传输的安全性,那用两组公钥私钥,是不是就能保证双向传输都安全了?请看下面的过程:

  1. 某网站拥有用于非对称加密的公钥A、私钥A’;浏览器拥有用于非对称加密的公钥B、私钥B’。
  2. 浏览器像网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 浏览器把公钥B明文传输给服务器。
  4. 之后浏览器向服务器传输的所有东西都用公钥A加密,服务器收到后用私钥A’解密。由于只有服务器拥有这个私钥A’可以解密,所以能保证这条数据的安全。
  5. 服务器向浏览器传输的所有东西都用公钥B加密,浏览器收到后用私钥B’解密。同上也可以保证这条数据的安全。

的确可以!抛开这里面仍有的漏洞不谈(下文会讲),HTTPS的加密却没使用这种方案,为什么?最主要的原因是非对称加密算法非常耗时,特别是加密解密一些较大数据的时候有些力不从心,而对称加密快很多,看来必须得用对称加密,那我们能不能运用非对称加密的特性解决前面提到的对称加密的问题?

非对称加密+对称加密?

既然非对称加密耗时,非对称加密+对称加密结合可以吗?而且得尽量减少非对称加密的次数。当然是可以的,而且非对称加密、解密各只需用一次即可。
请看一下这个过程:

  1. 某网站拥有用于非对称加密的公钥A、私钥A’。
  2. 浏览器像网站服务器发送请求,服务器把公钥A明文给传输浏览器。
  3. 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
  4. 服务器拿到后用私钥A’解密得到密钥X。
  5. 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都用密钥X加密解密。

完美!HTTPS基本就是采用了这种方案。完美?还是有漏洞的。

中间人攻击

中间人的确无法得到浏览器生成的密钥B,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开拿到它呀!然而中间人却完全不需要拿到密钥A’就能干坏事了。请看:

  1. 某网站拥有用于非对称加密的公钥A、私钥A’
  2. 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 中间人劫持到公钥A,保存下来,把数据包中的公钥A替换成自己伪造的公钥B(它当然也拥有公钥B对应的私钥B’)
  4. 浏览器随机生成一个用于对称加密的密钥X,用公钥B(浏览器不知道公钥被替换了)加密后传给服务器。
  5. 中间人劫持后用私钥B’解密得到密钥X,再用公钥A加密后传给服务器
  6. 服务器拿到后用私钥A’解密得到密钥X。

这样在双方都不会发现异常的情况下,中间人得到了密钥X。根本原因是浏览器无法确认自己收到的公钥是不是网站自己的。那么下一步就是解决下面这个问题:

如何证明浏览器收到的公钥一定是该网站的公钥?

现实生活中,如果想证明某身份证号一定是小明的,怎么办?看身份证。这里政府机构起到了“公信”的作用,身份证是由它颁发的,它本身的权威可以对一个人的身份信息作出证明。互联网中能不能搞这么个公信机构呢?给网站颁发一个“身份证”?

数字证书

网站在使用HTTPS前,需要向“CA机构”申请颁发一份数字证书,数字证书里有证书持有者、证书持有者的公钥等信息,服务器把证书传输给浏览器,浏览器从证书里取公钥就行了,证书就如身份证一样,可以证明“该公钥对应该网站”。然而这里又有一个显而易见的问题了,证书本身的传输过程中,如何防止被篡改?即如何证明证书本身的真实性?身份证有一些防伪技术,数字证书怎么防伪呢?解决这个问题我们就基本接近胜利了!

如何放防止数字证书被篡改?

我们把证书内容生成一份“签名”,比对证书内容和签名是否一致就能察觉是否被篡改。这种技术就叫数字签名

数字签名

数字签名的制作过程:

  1. CA拥有非对称加密的私钥和公钥。
  2. CA对证书明文信息进行hash。
  3. 对hash后的值用私钥加密,得到数字签名。

明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了。
那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的?(有没有被篡改、掉包)

浏览器验证过程:

  1. 拿到证书,得到明文T,数字签名S。
  2. 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S’。
  3. 用证书里说明的hash算法对明文T进行hash得到T’。
  4. 比较S’是否等于T’,等于则表明证书可信。

中间人有可能篡改该证书吗?

假设中间人篡改了证书的原文,由于他没有CA机构的私钥,所以无法得到此时加密后签名,无法相应地篡改签名。浏览器收到该证书后会发现原文和签名解密后的值不一致,则说明证书已被篡改,证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。
既然不可能篡改,那整个证书被掉包呢?

中间人有可能把证书掉包吗?

假设有另一个网站B也拿到了CA机构认证的证书,它想搞垮网站A,想劫持网站A的信息。于是它成为中间人拦截到了A传给浏览器的证书,然后替换成自己的证书,传给浏览器,之后浏览器就会错误地拿到B的证书里的公钥了,会导致上文提到的漏洞。
其实这并不会发生,因为证书里包含了网站A的信息,包括域名,浏览器把证书里的域名与自己请求的域名比对一下就知道有没有被掉包了。

为什么制作数字签名时需要hash一次?

我初学HTTPS的时候就有这个问题,似乎以上过程中hash有点多余,把hash过程去掉也能保证证书没有被篡改。
最显然的是性能问题,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加密解密就会快很多。

怎么证明CA机构的公钥是可信的?

操作系统、浏览器本身会预装一些它们信任的根证书,如果其中有该CA机构的根证书,那就可以拿到它对应的可信公钥了。

实际上证书之间的认证也可以不止一层,可以A信任B,B信任C,以此类推,我们把它叫做信任链数字证书链,也就是一连串的数字证书,由根证书为起点,透过层层信任,使终端实体证书的持有者可以获得转授的信任,以证明身份。

另外,不知你们是否遇到过网站访问不了、提示要安装证书的情况?这里安装的就是根证书。说明浏览器不认给这个网站颁发证书的机构,那么没有该机构的根证书,你就得手动下载安装(风险自己承担XD)。安装该机构的根证书后,你就有了它的公钥,就可以用它验证服务器发来的证书是否可信了。

对称密钥和公钥密码体制

  • 对称密钥密码体制
    • 加密密码和解密密码是相同的密钥
  • 公钥密码体制,非对称加密
    • 加密密码和解密密码不同
    • 加密和解密算法都是公开的,加密密钥也是公开的,解密密钥是保密的
    • 公钥和私钥是配对关系,公钥加密就用私钥解密,反之亦然

数字签名和数字证书

使用公钥密码加密的一般流程:通过A的公钥对报文加密,发送给B,然后B拿A的私钥进行解密,得到报文.
注意:并不是每次传输报文的时候都要加数字签名,数字签名一般用于数字证书的验证,这样的话浏览器内置的CA拥有服务端的公钥和私钥。

  • 数字签名

    • 普通数字签名(能核实发送者,但无法保证报文完整性)

      • A通过A的私钥对报文进行加密,将其附在报文的后面,发送给B,然后B拿A的公钥对附加信息进行解密的过程,为数字签名
      • 上述过程中仅仅实现了数字签名,但并没有对实际报文进行加密。实际操作时,可以通过A–>A私钥(数字签名)–>B公钥(报文加密)–>B私钥(报文解密)–>A公钥(验证数字签名)
    • 密码散列函数

      • 使用密码散列函数对报文进行与运算得到hash值,简称摘要
      • 密码散列函数有MD5和安全散列算法SHA
    • 报文摘要数字签名(核实发送者,保证报文完整性)
      对报文本身加密可能是个耗时过程,比如这封Email足够大,那么私钥加密整个文件以及拿到文件后的解密无疑是巨大的开销

      • A先对这封Email执行哈希运算得到hash值简称“摘要”,取名h1
      • 然后用自己私钥对摘要加密,生成的东西叫“数字签名”
      • 把数字签名加在Email正文后面,一起发送给B
      • 防止邮件被窃听你可以用继续B公钥加密
      • B收到邮件后使用B私钥对报文解密,用A的公钥对数字签名解密,成功则代表Email确实来自A,失败说明有人冒充
      • B对邮件正文执行哈希运算得到hash值,取名h2
      • B会对比数字签名的hash值h1和自己运算得到的h2,一致则说明邮件未被篡改。
    • 数字签名的作用

      • 确认核实发送者
      • 保证报文的完整性
      • 一般用于验证数字证书
  • 数字证书
    明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了,由认证中心(CA)或者认证中心的下级认证中心颁发。通俗来说,A确认收到的公钥真的是B的公钥,而不是别人伪造的

    • 制作数字签名
      • CA拥有非对称加密的私钥和公钥。
      • CA对证书明文信息进行hash。
      • 对hash后的值用私钥加密,得到数字签名
      • 明文和数字签名共同组成了数字证书
    • 数字证书验证过程
      • 拿到证书,得到明文T,数字签名S。
      • 用CA机构的公钥对S解密,得到S’。(由于是浏览器信任的机构,浏览器保有它的公钥,操作系统、浏览器本身会预装一些它们信任的根证书,如果其中有该CA机构的根证书,那就可以拿到它对应的可信公钥)
      • 用证书里说明的hash算法对明文T进行hash得到T’。
      • 比较S’是否等于T’,等于则表明证书可信。

HTTP和HTTPS的区别

  • HTTP协议是以明文的方式在网络中传输数据,而HTTPS协议传输的数据则是经过TLS加密后的,HTTPS具有更高的安全性
  • HTTPS可以保证报文完整性,另外可以核实发送者身份
  • HTTPS协议需要服务端申请证书,浏览器端安装对应的根证书
  • HTTPS在TCP三次握手阶段之后,还需要进行SSL的handshake,协商加密使用的对称加密密钥
  • HTTP协议端口是80,HTTPS协议端口是443

HTTPS加密过程

  • 传统的HTTP协议通信:传统的HTTP报文是直接将报文信息传输到TCP然后TCP再通过TCP套接字发送给目的主机上。

  • HTTPS协议通信:HTTPS是HTTP报文直接将报文信息传输给SSL套接字进行加密,SSL加密后将加密后的报文发送给TCP套接字,然后TCP套接字再将加密后的报文发送给目的主机,目的主机将通过TCP套接字获取加密后的报文给SSL套接字,SSL解密后交给对应进程。

  1. 认证服务器。浏览器内置一个受信任的CA机构列表,并保存了这些CA机构的证书。第一阶段服务器会提供经CA机构认证颁发的服务器证书,如果认证该服务器证书的CA机构,存在于浏览器的受信任CA机构列表中,并且服务器证书中的信息与当前正在访问的网站(域名等)一致,那么浏览器就认为服务端是可信的,并从服务器证书中取得服务器公钥,用于后续流程。否则,浏览器将提示用户,根据用户的选择,决定是否继续。当然,我们可以管理这个受信任CA机构列表,添加我们想要信任的CA机构,或者移除我们不信任的CA机构。
  2. 协商会话密钥。客户端在认证完服务器,获得服务器的公钥之后,利用该公钥与服务器进行加密通信,协商出两个会话密钥,分别是用于加密客户端往服务端发送数据的客户端会话密钥,用于加密服务端往客户端发送数据的服务端会话密钥。在已有服务器公钥,可以加密通讯的前提下,还要协商两个对称密钥的原因,是因为非对称加密相对复杂度更高,在数据传输过程中,使用对称加密,可以节省计算资源。另外,会话密钥是随机生成,每次协商都会有不一样的结果,所以安全性也比较高。
  3. 加密通讯。此时客户端服务器双方都有了本次通讯的会话密钥,之后传输的所有Http数据,都通过会话密钥加密。这样网路上的其它用户,将很难窃取和篡改客户端和服务端之间传输的数据,从而保证了数据的私密性和完整性。

SSL常见加密算法

对称加密算法

  • DES:数据加密标准,速度较快,适用于加密大量数据的场合。
  • 3DES:是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
  • AES:高级加密标准,是下一代的加密算法标准,速度快,安全级别高。

非对称加密算法

  • RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的。
  • DSA:数字签名算法,是一种标准的 DSS(数字签名标准)。
  • ECC:椭圆曲线密码编码学。

运输层安全协议及SSL工作过程

  • SSL 安全套接字层协议
  • TLS 运输层安全协议,在SSL的基础上设计
  • SSL工作过程
    • 协商加密算法
      • 浏览器A向服务器B发送SSL版本,及自身支持的加密组件(包括加密算法及密钥长度等)
      • B从中选择自身支持的加密组件和SSL版本,发送给A
    • 服务器鉴别
      • B向A发送包含公开密钥的数字证书
      • A对数字证书进行鉴别,获取B的公钥
    • 会话密钥计算
      • A随机产生秘密数,将秘密数通过B的公钥发送给B,之后A通过协商的加密算法产生会话密钥
      • B接收到秘密数后,通过B的私钥将其解密得到秘密数,然后根据协商加密算法产生会话密钥
    • 安全数据传输
      • 双方会互相发送一次数据,用会话密钥加密和解密他们之间传达的数据并验证其完整性
    • 通信
      • 上述验证通过后,才继续进行http通信

HTTPS必须在每次请求中都要先在SSL/TLS层进行握手传输密钥吗?

显然每次请求都经历一次密钥传输过程非常耗时,那怎么达到只传输一次呢?用session就行。

  • 服务器会为每个浏览器(或客户端软件)维护一个session ID,在TSL握手阶段传给浏览器,浏览器生成好密钥传给服务器后,服务器会把该密钥存到相应的session ID下
  • 之后浏览器每次请求都会携带session ID,服务器会根据session ID找到相应的密钥并进行解密加密操作,这样就不必要每次重新制作、传输密钥了!

cookie和session

HTTP协议作为无状态协议,对于HTTP协议而言,无状态指每次request请求之前是相互独立的,当前请求并不会记录它的上一次请求信息,如何将上下文请求进行关联呢?客户端(不同的浏览器)记录用户的状态通过cookie,服务器端(不同的网站)记录用户的状态通过session。

cookie

Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。

工作流程

  • 客户端请求服务器端,服务器端产生cookie响应头,随响应报文发送给客户端(cookie存放在响应报文的头部),客户端将cookie文本保存起来
  • 下次客户端再次请求服务端时,会产生cookie请求头,将之前服务器发送的cookie信息,再发送给服务器,服务器就可以根据cookie信息跟踪客户端的状态。

基础知识

Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie,它是服务器端存放在本地机器中的数据,随每一个请求发送给服务器,由于Cookie在客户端,所以可以编辑伪造,不是十分安全。

  • 非持久cookie
    • 内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。
  • 持久cookie
    • 硬盘Cookie保存在硬盘里,有一个过期时间(客户端cookie设置的时间),除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。

session

Session是另一种记录客户状态的机制,它是在服务端保存的一个数据结构(主要存储的的SessionID和Session内容,同时也包含了很多自定义的内容如:用户基础信息、权限信息、用户机构信息、固定变量等),这个数据可以保存在集群、数据库、文件中,用于跟踪用户的状态。

客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

工作流程

  • 当用户第一次访问站点时,服务器端为用户创建一个sessionID,这就是针对这个用户的唯一标识,每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。这样客户端就会拥有一个该站点给他的session ID。
  • 当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就跟第一次一样再创建个新的。

基础知识

session是存放在服务器里的,所以session 里的东西不断增加会增加服务器的负担,我们会把一些重要的东西放在session里,不太重要的放在客户端cookie里

  • session失效

    • 服务器(非正常)关闭时
    • session过期/失效(默认30分钟)
      • 问题:时间的起算点 从何时开始计算30分钟?从不操作服务器端的资源开始计时(例如:当你访问淘宝页面时,点开页面不动,第29分钟再动一下页面,就得重新计时30分钟;当过了30分钟,就失效了。)
    • 手动销毁session
  • sessionID的传递方式

    • 通过cookie传递
    • 当cookie禁用后,可以通过url传递
  • 不同场景下的session

    • 当在同一个浏览器中同时打开多个标签,发送同一个请求或不同的请求,仍是同一个session;
    • 当不在同一个窗口中打开相同的浏览器时(打开多个相同的浏览器),发送请求,仍是同一个session;
    • 当使用不同的浏览器时,发送请求,即使发送相同的请求,是不同的session;
    • 当把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时,是不同的session。

区别

  • cookie数据存放在客户的浏览器上,session数据放在服务器上。
  • cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
  • session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
  • 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
  • 可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。

cookie防伪

服务器为每个Cookie项生成签名。如果用户篡改Cookie,则与签名无法对应上。以此,来判断数据是否被篡改。

原理如下:

  • 服务端提供一个签名生成算法secret
  • 根据方法生成签名secret(wall)=34Yult8i
  • 将生成的签名放入对应的Cookie项username=wall|34Yult8i。其中,内容和签名用|隔开。
  • 服务端根据接收到的内容和签名,使用签名生成算法对username进行签名,与传输过来的签名进行比对,如果一致,表明没有被伪造。

token

Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌。当客户端第一次访问服务端,服务端会根据传过来的唯一标识userId,运用一些算法,并加上密钥,生成一个Token,然后通过BASE64编码一下之后将这个Token返回给客户端,客户端将Token保存起来(可以通过数据库或文件形式保存本地)。下次请求时,客户端只需要带上Token,服务器收到请求后,会用相同的算法和密钥去验证Token。

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  • 客户端使用用户名跟密码请求登录
  • 服务端收到请求,去验证用户名与密码
  • 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  • 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者数据库里
  • 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  • 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

浏览器关闭后,session就销毁了吗?

浏览器关闭和服务器session销毁没有任何关系,会话Cookie(非持久cookie)在关闭浏览器后就会消失,但是原来服务器的Session还在,只有等到了销毁的时间会自动销毁。

HTTPS过慢如何优化

HTTPS 连接大致上可以划分为两个部分,第一个是建立连接时的非对称加密握手,第二个是握手后的对称加密报文传输

由于目前流行的 AES(高级加密标准)、ChaCha20 (加密算法)性能都很好,还有硬件优化,报文传输的性能损耗可以说是非常地小,小到几乎可以忽略不计了。所以,通常所说的“HTTPS 连接慢”指的就是刚开始建立连接的那段时间。

在 TCP 建连之后,正式数据传输之前,HTTPS 比 HTTP 增加了一个 TLS 握手的步骤,这个步骤最长可以花费两个消息往返,也就是 2-RTT。而且在握手消息的网络耗时之外,还会有其他的一些“隐形”消耗,比如:

产生用于密钥交换的临时公私钥对(ECDHE);

验证证书时访问 CA 获取 CRL 或者 OCSP;

非对称加密解密处理“Pre-Master”。

在最差的情况下,也就是不做任何的优化措施,HTTPS 建立连接可能会比 HTTP 慢上几百毫秒甚至几秒,这其中既有网络耗时,也有计算耗时,就会让人产生“打开一个 HTTPS 网站好慢啊”的感觉。

​ 不过刚才说的情况早就是“过去时”了,现在已经有了很多行之有效的 HTTPS 优化手段,运用得好可以把连接的额外耗时降低到几十毫秒甚至是“零”。

硬件优化

在计算机世界里的“优化”可以分成“硬件优化”和“软件优化”两种方式,先来看看有哪些硬件的手段。

首先,你可以选择更快的 CPU,最好还内建 AES 优化,这样即可以加速握手,也可以加速传输。

其次,你可以选择“SSL 加速卡”,加解密时调用它的 API,让专门的硬件来做非对称加解密,分担 CPU 的计算压力。

不过“SSL 加速卡”也有一些缺点,比如升级慢、支持算法有限,不能灵活定制解决方案等。

所以,就出现了第三种硬件加速方式:“SSL 加速服务器”,用专门的服务器集群来彻底“卸载”TLS 握手时的加密解密计算,性能自然要比单纯的“加速卡”要强大的多。

软件优化

不过硬件优化方式中除了 CPU,其他的通常可不是靠简单花钱就能买到的,还要有一些开发适配工作,有一定的实施难度。比如,“加速服务器”中关键的一点是通信必须是“异步”的,不能阻塞应用服务器,否则加速就没有意义了。

所以,软件优化的方式相对来说更可行一些,性价比高,能够“少花钱,多办事”。

软件方面的优化还可以再分成两部分:一个是软件升级,一个是协议优化

软件升级

实施起来比较简单,就是把现在正在使用的软件尽量升级到最新版本,比如把 Linux 内核由 2.x 升级到 4.x,把 Nginx 由 1.6 升级到 1.16,把 OpenSSL 由 1.0.1 升级到 1.1.0/1.1.1。

由于这些软件在更新版本的时候都会做性能优化、修复错误,只要运维能够主动配合,这种软件优化是最容易做的,也是最容易达成优化效果的。

协议优化

​ 从刚才的 TLS 握手图中你可以看到影响性能的一些环节,协议优化就要从这些方面着手,先来看看核心的密钥交换过程。

​ 如果有可能,应当尽量采用 TLS1.3,它大幅度简化了握手的过程,完全握手只要 1-RTT,而且更加安全。

​ 如果暂时不能升级到 1.3,只能用 1.2,那么握手时使用的密钥交换协议应当尽量选用椭圆曲线的 ECDHE 算法。它不仅运算速度快,安全性高,还支持“False Start”,能够把握手的消息往返由 2-RTT 减少到 1-RTT,达到与 TLS1.3 类似的效果。

你可能感兴趣的:(计算机网络)