计算机网络体系结构
传输层:TCP和UDP
什么是三次握手?
什么是四次挥手?
TCP如何实现流量控制?
TCP的拥塞控制是怎么实现的?
TCP如何最大利用带宽?
TCP与UDP的区别
TCP如何保证传输的可靠性
什么是TCP粘包?
应用层:HTTP和HTTPS
HTTP和HTTPS有什么区别?
GET与POST的区别?
Session与Cookie的区别?
从输入网址到获得页面的过程 (越详细越好)?
HTTP请求有哪些常见状态码?
什么是RIP (距离矢量路由协议)?
网络层协议
IP地址的分类?
什么叫划分子网?
什么是ARP协议?
什么是NAT (网络地址转换)?
参考
osi七层参考模型;tcp/ip五层(或四层)
分层是为了给网络协议的设计提供一个结构,每一层向它的上一层提供服务,采用自上而下的方法研究其原理。
OSI中的表示层主要包括数据压缩,数据加密和数据描述;会话层提供了数据交换的功能
应用层:存放网络应用程序和网络协议,包括许多常见协议。应用层只需要专注于为用户提供应用功能。
应用层是工作在操作系统中的用户态,传输层及以下则工作在内核态。
ping:
FTP(21端口):文件传输协议 SSH(22端口):远程登陆 TELNET(23端口):远程登录 SMTP(25端口):发送邮件 POP3(110端口):接收邮件 HTTP(80端口):超文本传输协议 DNS(53端口):运行在UDP上,域名解析服务 Socket:应用层
传输层(进行数据的传输):为应用层提供网络支持。 两个传输协议:TCP/UDP
大部分应用使用的是TCP,比如http。
网络层(寻址):网络层负责将数据从一个设备传输到另一个设备。
不希望传输层协议处理太多的事情,只需要服务好应用,让传输层作为应用间数据传输的媒介,帮助实现应用到应用的通信,而实际的传输功能就交给下一层,也就是网络层完成。
IP、ARP、NAT、RIP、...路由器
通过IP地址进行寻址,根据IP地址和子网掩码可以计算出网络号(标识属于哪个子网)和主机号(标识子网下的不同主机)。
IP协议还有路由的功能,当数据包到达一个网络节点,就需要通过路由算法决定下一步走哪条路径。
10.100.122.0/24,后面的/24表示就是 255.255.255.0 子网掩码,共24个1. 10.100.122.2 和 255.255.255.0 进行按位与运算,就可以得到网络号。 255.255.255.0 取反后与IP地址进行按位与运算,就可以得到主机号。
链路层:把数据包从一个节点(主机或路由器)运输到另一个节点。
以太网接入的DOCSIS协议,MAC地址(IP地址为32位,MAC地址为48位);网桥,交换机
物理层:把一个个比特从一个节点运到另一个节点。协议与实际的物理传输介质有关。
中继器、集线器
TCP:面向连接的、可靠的、基于字节流的传输层通信协议
为什么需要 TCP ?
IP层是不可靠的,不能保证网络包的交付,按序交付以及数据的完整性。要保证网络数据包的可靠性,需要上层(传输层)的tcp协议负责。
TCP四元组可以唯一的确定一个连接:源地址,源端口,目的地址,目的端口。
源地址和目的地址(32位)在IP头部,通过IP协议发送吧报文给对方主机。
源端口和目的端口(16位)在TCP头部,告诉TCP协议应该把保文发给哪个进程。
TCP头格式:源端口号,序列号,确认应答号,控制位,数据。
序列号seq:建立连接时由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机,每发送一次数据,就累加一次该数据字节数的大小。用来解决网络包乱序问题。 确认应答号ack:指下一次期望收到的数据的序列号,发送端收到这个确认应答后可以认为在这个序列号以前的数据都已经被正常接收。用来解决丢包的问题。 控制位: SYN:该位为1时,表示希望建立连接,并在其【序列号】的字段进行序列号初始值的设定。 FIN:该位为1时,表示今后不会再有数据发送,希望【断开连接】。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN位为1的TCP段。 ACK:该位为1时,【确认应答】的字段变为有效,TCP规定除了最初建立连接时的SYN包之外该位必须设置为1。 RST:该位为1时,表示TCP连接中出现异常必须强制断开连接。
第一次握手:客户端将SYN位置1,随机产生一个初始序列号seq发送给服务端,进入SYN_SENT状态;(保证了客户端的发送能力没问题)
第二次握手:服务端收到客户端的SYN=1之后,知道客户端请求建立连接,将自己的SYN置1,ACK置1,产生一个确认应答号ack=seq+1,并随机产生一个自己的初始序列号seq,发送给客户端;进入SYN_RCVD状态;(服务端的接收能力以及发送能力没问题)
第三次握手:客户端检查ack是否为序列号seq+1,ACK是否为1,检查正确之后将自己的ACK置为1,产生一个ack=服务器发的序列号seq+1,发送给服务器;进入ESTABLISHED状态;服务器检查ACK为1和ack为序列号seq+1之后,也进入ESTABLISHED状态;完成三次握手,连接建立。(保证客户端的接收能力没问题)
可以两次握手吗?
不可以。有两个原因:
1.可能会出现已失效的连接请求报文段又传到了服务器端。
client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。
2.两次握手无法保证Client正确接收第二次握手的报文(Server无法确认Client是否收到),也无法保证Client和Server之间成功互换初始序列号。
可以四次握手吗?
可以。但是会降低传输的效率。
四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。
握手丢失会发生什么
第一次握手丢失了,会发生什么?
如果客户端迟迟借不到服务器SYN-ACK报文,触发超时重传机制(重传的SYN序号是一样的),每次超时时间是上一次的2倍。也会又重传次数。当已经达到最大重传次数的时候,等待一段时间(时间是上一次超时重传的2倍),如果还没有收到,就会断开连接。
第二次握手丢失了,会发生什么?
客户端没有收到,回触发超时重传机制,重传SYN报文。
服务器端也没有收到ACK确认报文,回触发超时重传机制,重传SYN-ACK报文。
第三次握手,如果客户端的ACK未送达服务器?
Server端: 由于Server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发五次,之后自动关闭连接进入CLOSED状态),Client收到后会重新传ACK给Server。
Client端,两种情况:
在Server进行超时重发的过程中,如果Client向服务器发送数据,数据头部的ACK是为1的,所以服务器收到数据之后会读取 ACK number,进入 establish 状态
在Server进入CLOSED状态之后,如果Client向服务器发送数据,服务器会以RST包应答。
如果已经建立了连接,但客户端出现了故障怎么办?
服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
如果已经建立连接,但是服务端进程崩溃回发生什么?
TCP的连接信息是由内核维护的,所以当服务器的进程崩溃后,内核需要挥手该进程所有TCP连接资源,于是你和核客户端完成TCP四次挥手。
初始序列号是什么?
TCP连接的一方A,随机选择一个32位的序列号(Sequence Number)作为发送数据的初始序列号(Initial Sequence Number,ISN),比如为1000,以该序列号为原点,对要传送的数据进行编号:1001、1002...三次握手时,把这个初始序列号传送给另一方B,以便在传输数据时,B可以确认什么样的数据编号是合法的;同时在进行数据传输时,A还可以确认B收到的每一个字节,如果A收到了B的确认编号(acknowledge number)是2001,就说明编号为1001-2000的数据已经被B成功接受。
什么是SYN攻击?如何避免
TCP三次握手,攻击者短时间伪造SYN,服务器回回应SYN——ACK,但是得不到回应,久而久之,就会沾满服务器的半连接队列,使得服务器不能为正常用户服务。
SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满,这样**当 TCP 半连接队列满了,后续再在收到 SYN 报文就会丢弃**,导致客户端无法和服务端建立连接。
避免 SYN 攻击方式,可以有以下四种方法:
调大 netdev_max_backlog;
增大 TCP 半连接队列;
开启 tcp_syncookies;
减少 SYN+ACK 重传次数
第一次挥手:Client将FIN置为1,发送一个序列号seq给Server;进入FIN_WAIT_1状态;
第二次挥手:Server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
第三次挥手:Server将FIN置1,发送一个序列号给Client;进入LAST_ACK状态;
第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?
因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。
如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
客户端没有收到ACK确认,会重新发送FIN请求。
客户端TIME_WAIT状态的意义是什么?
第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。
MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
大量的 TIME_WAIT 状态 TCP 连接存在,其本质原因是什么?
1.大量的短连接存在
2.特别是 HTTP 请求中,如果 connection 头部取值被设置为 close 时,基本都由「服务端」发起主动关闭连接
3.而,TCP 四次挥手关闭连接机制中,为了保证 ACK 重发和丢弃延迟数据,设置 time_wait 为 2 倍的 MSL(报文最大存活时间)
TIME_WAIT 状态:
1.TCP 连接中,主动关闭连接的一方出现的状态;(收到 FIN 命令,进入 TIME_WAIT 状态,并返回 ACK 命令)
2.保持 2 个 MSL 时间,即,4 分钟;(MSL 为 2 分钟)
解决办法 解决上述 time_wait 状态大量存在,导致新连接创建失败的问题,一般解决办法:
1.客户端,HTTP 请求的头部,connection 设置为 keep-alive,保持存活一段时间:现在的浏览器,一般都这么进行了
2.服务器端
允许 time_wait 状态的 socket 被重用
缩减 time_wait 时间,设置为 1 MSL
TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。
窗口大小由接收方控制。
使用滑动窗口协议实现流量控制。防止发送方发送速率太快,接收方缓存区不够导致溢出。接收方会维护一个接收窗口 receiver window(窗口大小单位是字节),接受窗口的大小是根据自己的资源情况动态调整的,在返回ACK时将接受窗口大小放在TCP报文中的窗口字段告知发送方。发送窗口的大小不能超过接受窗口的大小,只有当发送方发送并收到确认之后,才能将发送窗口右移。
发送窗口的上限为接受窗口和拥塞窗口中的较小值。接受窗口表明了接收方的接收能力,拥塞窗口表明了网络的传送能力。
什么是零窗口(接收窗口为0时会怎样)?
如果接收方没有能力接收数据,就会将接收窗口设置为0,这时发送方必须暂停发送数据,但是会启动一个持续计时器(persistence timer),到期后发送一个大小为1字节的探测数据包,以查看接收窗口状态。如果接收方能够接收数据,就会在返回的报文中更新接收窗口大小,恢复数据传送。
窗口关闭潜在的危险
当发生窗口关闭时,接收方处理完数据后,会向发送方通告一个窗口非 0 的 ACK 报文,如果这个通告窗口的 ACK 报文在网络中丢失了,那麻烦就大了。
这会导致发送方一直等待接收方的非 0 窗口通知,接收方也一直等待发送方的数据,如不采取措施,这种相互等待的过程,会造成了死锁的现象。
TCP 是如何解决窗口关闭时,潜在的死锁现象呢?
TCP 为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。如果持续计时器超时,就会发送窗口探测 ( Window probe ) 报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小。
其实只要「发送方」没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了拥塞
拥塞控制主要由四个算法组成:慢启动(Slow Start)、拥塞避免(Congestion voidance)、快重传 (Fast Retransmit)、快恢复(Fast Recovery)
慢启动:刚开始发送数据时,先把拥塞窗口(congestion window)设置为一个最大报文段MSS的数值,每收到一个新的确认报文之后,就把拥塞窗口加1个MSS。这样每经过一个传输轮次(或者说是每经过一个往返时间RTT),拥塞窗口的大小就会加倍
拥塞避免:当拥塞窗口的大小达到慢开始门限(slow start threshold)时,开始执行拥塞避免算法,拥塞窗口大小不再指数增加,而是线性增加,即每经过一个传输轮次只增加1MSS.
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。(这是不使用快重传的情况)
快重传:快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
快恢复:当发送方连续收到三个重复确认时,就把慢开始门限减半,然后执行拥塞避免算法。不执行慢开始算法的原因:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方认为现在网络可能没有出现拥塞。 也有的快重传是把开始时的拥塞窗口cwnd值再增大一点,即等于 ssthresh + 3*MSS 。这样做的理由是:既然发送方收到三个重复的确认,就表明有三个分组已经离开了网络。这三个分组不再消耗网络的资源而是停留在接收方的缓存中。可见现在网络中减少了三个分组。因此可以适当把拥塞窗口扩大些。
数据包校验
对失序数据包重新排序(TCP报文具有序列号)
丢弃重复数据
应答机制:接收方收到数据之后,会发送一个确认(通常延迟几分之一秒);
超时重发:发送方发出数据之后,启动一个定时器,超时未收到接收方的确认,则重新发送这个数据;
流量控制:确保接收端能够接收发送方的数据而不会缓冲区溢出
TCP速率受到三个因素影响
窗口:即滑动窗口大小,见TCP如何实现流量控制?
带宽:这里带宽是指单位时间内从发送端到接收端所能通过的“最高数据率”,是一种硬件限制。TCP发送端和接收端的数据传输数不可能超过两点间的带宽限制。发送端和接收端之间带宽取所通过线路的带宽最小值(如通过互联网连接)。
RTT:即Round Trip Time,表示从发送端到接收端的一去一回需要的时间,TCP在数据传输过程中会对RTT进行采样(即对发送的数据包及其ACK的时间差进行测量,并根据测量值更新RTT值),TCP根据得到的RTT值更新RTO值,即Retransmission TimeOut,就是重传间隔,发送端对每个发出的数据包进行计时,如果在RTO时间内没有收到所发出的数据包的对应ACK,则任务数据包丢失,将重传数据。一般RTO值都比采样得到的RTT值要大。
带宽时延乘积
带宽时延乘积=带宽*RTT,实际上等于发送端到接收端单向通道的数据容积的两倍,这里单向通道的数据容积可以这样来理解,单向通道看成是一条单行道马路,带宽就是马路的车道数,路上跑的汽车就是数据(不过这里所有汽车的速率都是一样的,且不会有人想超车,大家齐头并进),那么单向通道的数据容积就是这条单行道上摆满车,一共可以摆多少辆。带宽就是马路的车道数,带宽数乘以单向通道的数据容积就是路面上所能容纳的全部数据量。当路面上已经摆满的时候,就不能再往里面放了。
设滑动窗口大小为, 发送端和接收端的带宽为, RTT为。
前面已经说过了,TCP发送数据时受滑动窗口的限制,当TCP将滑动窗口中的数据都发出后,在收到第一个ACK之前,滑动窗口大小是0,不能再发送数据了,必须等待ACK包使滑动窗口移动。那么在理想情况下,ACK包应该在什么时候到达呢?显然,就是在数据发出后的RTT时间后,ACK包到达。这也就是说,现在在不考虑丢包和拥塞情况下,TCP在一个RTT时间内能发出的最大数据量为 ,所以不考虑带宽限制下,TCP能一个时刻能达到的最大速度是 。
现在再考虑带宽限制,前面说过当马路上摆满车的时候,就无法再往里放车了,同理,TCP发送端在 时间内,能往通道上放的最大数据量为 ,通过带宽时延乘积得到的容积限制为 。当 时,单向通道容积不构成瓶颈,速率的限制主要来源于窗口大小限制。而当 时,则就受到容积限制,即此时速率限制来源于带宽限制。
因此,TCP的最大速率为
在我们平时生活中使用的宽带网络,ADSL等环境下,因为带宽都比较小,从而 也比较小,再加上网络情况比较复杂,拥塞情况比较常见,所以这些网络环境下,TCP速率的主要限制因素在于带宽,丢包率等。长肥管道一般不太常见,多见于一些单位使用的专线网络,在这些网络中速率的主要限制因素就是窗口大小了,这也是传统TCP在这些网络环境中不能充分利用带宽的原因所在(因为传统TCP的窗口大小是用2字节表示的,所以最大只有65535(不考虑窗口扩大选项)),除了专线网络外,随着网络硬件技术的发展,万兆交换机的出现,局域网中也可能会出现带宽时延乘积较大的情况。
TCP实现可靠传输的方式之一,是通过序列号与确认应答。
重传机制:RTT(往返时延数据发送时刻到接收到确认的时刻的差值)
超时重传:在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据,也就是我们常 说的超时重传。RTO超时重传时间。超时重传时间 RTO 的值应该略大于报文往返 RTT 的值。 快速重传(Fast Retransmit)机制:快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文 段。 SACK 方法:在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将已收到的数据的信息发送给「发送方」,这样发送方就可以知 道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。 Duplicate SACK:使用了 SACK 来告诉「发送方」有哪些数据被重复接收了。
TCP:传输控制协议 UDP:用户数据报协议
TCP是面向连接的,UDP是无连接的;
UDP发送数据之前不需要建立连接。
TCP是可靠的,UDP不可靠;
UDP接收方收到报文后,不需要给出任何确认。不能保证将数据传送到目标。 TCP 相比 UDP 多了很多特性,比如流量控制、超时重传、拥塞控制等,这些都是为了保证数据包能可靠地传输给对方。 UDP 也可以实现可靠传输,把 TCP 的特性在应用层上实现就可以,不过要实现一个商用的可靠 UDP 传输协议,也不是一件简单的事情。
TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
TCP是面向字节流的,UDP是面向报文的;
面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP一个报文只能一次发完。 TCP 报文是有序的,当前一个TCP 报文没有收到的时候,即使它先收到了后面的 TCP 报文,那么也不能扔给应用层去处理,同时对重复的 TCP 报文会自动丢弃。
传输方式不同
TCP是流式传输,没有边界,但保证顺序和可靠。 UDP是一个包一个包的发送,是有边界的,但可能会丢包和乱序。
TCP有拥塞控制机制,UDP没有。
网络出现的拥塞不会使源主机的发送速率降低,这对某些实时应用是很重要的,比如媒体通信,游戏;
TCP首部开销(20字节)比UDP首部开销(8字节)要大
TCP头部还有序列号,确认应答号,控制位
UDP 的主机不需要维持复杂的连接状态表
什么时候选择TCP,什么时候选UDP?
对某些实时性要求比较高的情况,选择UDP,比如游戏,媒体通信,实时视频流(直播),即使出现传输错误也可以容忍;其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失
HTTP可以使用UDP吗?
HTTP不可以使用UDP,HTTP需要基于可靠的传输协议,而UDP不可靠
注:http 3.0 使用udp实现
面向连接和无连接的区别
无连接的网络服务(数据报服务)-- 面向连接的网络服务(虚电路服务)
虚电路服务:首先建立连接,所有的数据包经过相同的路径,服务质量有较好的保证;
数据报服务:每个数据包含目的地址,数据路由相互独立(路径可能变化);网络尽最大努力交付数据,但不保证不丢失、不保证先后顺序、不保证在时限内交付;网络发生拥塞时,可能会将一些分组丢弃;
浏览器查询 DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;
浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;
TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;
服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;
浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;
浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。
地址栏输入URL发生了什么
在浏览器中输入网址按下回车后: 1、DNS服务器进行域名映射,找到访问的地址,然后HTTP客户端进程在80端口发起一个服务器到访问地址的TCP连接,在客户和服务器进程中各有一个套接字socket与其相连。 2、客户端通过它的套接字发送http请求报文,服务器通过套接字接收报文,并解析。从存储器(RAM或磁盘)中检索出对象封装到响应报文中,通过套接字向客户端发送。 3、服务器通知TCP断开连接,实际是需要等到客户接受完响应报文后才会断开连接。 4、客户端接收完响应报文后,TCP连接关闭。客户端从响应报文中提取出HTML响应文件,然后循环检查报文中其他内部对象,检查完成后把对应的资源通过显示器呈现给用户。
HTTP是什么?
HTTP 是超文本传输协议
超文本:指传输的数据不仅包括文本,还包括图片、音频、视频,超链接等。
协议:是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。
传输:传输说明Http是传输协议。HTTP 协议是一个“双向协议”。数据虽然是在 A 和 B 之间传输,但并没有限制只有 A 和 B 这两个角色,允许中间有“中转”或者“接力”。
HTTP协议,就是指,客户端(服务端)和服务端之间通信时,发送的数据需要遵守的规则,叫HTTP协议。
常见状态码
1xx状态码:临时响应。表示临时响应并需要请求者继续执行操作的状态代码。
100:继续。请求者应当继续发起请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 101:切换协议。 请求者已要求服务器切换协议,服务器已确认并准备切换。
2xx状态码:操作成功。200 OK
200:成功。服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 201:已创建。请求成功并且服务器创建了新的资源。 202:已接受。服务器已接受请求,但尚未处理。 203:非授权信息。服务器已成功处理了请求,但返回的信息可能来自另一来源。 204:无内容。服务器成功处理了请求,但没有返回任何内容。 205:重置内容。服务器成功处理了请求,但没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。 206:部分内容。服务器成功处理了部分 GET 请求。
3xx状态码:重定向。表示要完成请求,需要进一步操作。
300:多种选择。针对请求,服务器可执行多种操作。服务器可根据请求者选择一项操作,或提供操作列表供请求者选择。 301:永久重定向。请求的网页已永久移动到新位置。 服务器返回此响应时,会自动将请求者转到新位置。 302:临时重定向。服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 303:查看其他位置。请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。 304:未修改。自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。 305:使用代理。请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。 //306:切换代理(已废弃) 307:临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 和302的唯一区别:307可以确保请求方法和消息主体不会发生变化。如果使用302响应状态码,一些旧客户端会错误地将请求方法转换为GET。
4xx状态码:客户端错误。400 Bad Request;401 Unauthorized;403 Forbidden;404 Not Found;
400:错误请求。服务器不理解请求的语法。 401:未授权。请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 //402:未付费(没实现) 403:禁止。服务器拒绝请求。 404:未找到。服务器找不到请求的网页。 405:方法禁用。禁用请求中指定的方法。 406:不接受。无法使用请求的内容特性响应请求的网页。 407:需要代理授权。此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。 408:请求超时。服务器等候请求时发生超时。 409:冲突。 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 410:已删除。如果请求的资源已永久删除,服务器就会返回此响应。 411:需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 412:未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 413:请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 414:请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 415:不支持的媒体类型) 请求的格式不受请求页面的支持。 416:请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 417:未满足期望值) 服务器未满足”期望”请求标头字段的要求。
400系列的错误信息,都是“用户不友好”的。在古老的互联网时代,当用户请求被拒绝时,返回一个简短的,代表错误原因的数字,是一种节省流量、节省服务器端和客户端CPU资源的行为。 但是随着互联网的发展,最佳的实践是,当用户的请求被拒绝时,网站(服务器端)应当重定向到一个合理的引流点。 例如,用户请求的资源不存在(404),可以重定向到网站首页、或者推荐其他内容;用户请求未授权内容(403),可以重定向到不需授权的内容;用户请求收费的内容但未付费(402),可以重定向到付费页面。
5xx状态码:服务端错误。500服务器内部错误;501服务不可用
500:服务器内部错误。服务器遇到错误,无法完成请求。 501:尚未实施。服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 502:错误网关。服务器作为网关或代理,从上游服务器收到无效响应。 503:服务不可。服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 504:网关超时。服务器作为网关或代理,但是没有及时从上游服务器收到请求。 505:HTTP 版本不受支持。服务器不支持请求中所用的 HTTP 协议版本。
常见字段
Host 字段:客户端发送请求时,用来指定服务器的域名。
Connection 字段:最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。
Content-Length 字段:服务器在返回数据时,会有 Content-Length
字段,表明本次回应的数据长度。
Content-Length: 1000 (本次服务器回应的数据长度是 1000 个字节)
Content-Type 字段:服务器返回的数据是什么格式。
Content-Type: text/html; charset=utf-8
Content-Encoding 字段:服务器返回的数据使用了什么压缩格式
Content-Encoding: gzip
HTTP1.1特性
简单,基本的报文格式就是header+body,头部信息也是key-value的形式,易于理解。
灵活和易拓展,HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充。
应用广泛和跨平台,从台式机的浏览器到手机上的各种 APP,从看新闻、刷贴吧到购物、理财、吃鸡,HTTP 的应用遍地开花,同时天然具有跨平台的优越性。
无状态:缺点
好处是服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。
坏处是服务器没有记忆能力,对于同一个用户的不同操作,都要问一遍身份信息。可以通过cookie解决。
明文传输:缺点
在传输过程中的信息,是可方便阅读的。但是不安全。
不安全:(缺点)明文传输,不验证通信方的身份,无法证明报文的完整性,可能被篡改。
如何优化HTTP
尽量避免发送 HTTP 请求;
通过缓存
在需要发送 HTTP 请求时,考虑如何减少请求次数;
减少重定向请求次数
重定向的工作交由代理服务器完成,就能减少 HTTP 请求次数了
合并请求
把多个访问小文件的请求合并成一个大的请求,虽然传输的总资源还是一样,但是减少请求,也就意味着减少了重复发送的 HTTP 头部。
但是这样的合并请求会带来新的问题,当大资源中的某一个小资源发生变化后,客户端必须重新下载整个完整的大资源文件,这显然带来了额外的网络消耗。
延迟发送请求
请求网页的时候,没必要把全部资源都获取到,而是只获取当前用户所看到的页面资源,当用户向下滑动页面的时候,再向服务器获取接下来的资源,这样就达到了延迟发送请求的效果。
减少服务器的 HTTP 响应的数据大小;
考虑对响应的资源进行压缩,这样就可以减少响应的数据大小,从而提高网络传输的效率。
HTTP 缓存技术
对于一些具有重复性的HTTP请求,比如每次请求得到的数据是一样的,就可以把这对请求-响应的数据都缓存到本地,下次就可以直接读取本地的数据,不用再获得服务器的响应了,从而提高性能。
强制缓存
只要浏览器判断缓存没有过期,就直接使用浏览器的本地缓存。决定是否使用缓存的主动性在于浏览器这边。
利用两个HTTP响应头部字段实现的,Cache-Control, 是一个相对时间; Expires,是一个绝对时间;都用来表示资源在客户端缓存的有效期。 优先用Cache-Control。 1.当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小; 2.浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器; 3.服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control。
协商缓存
当我们在浏览器使用开发者工具的时候,你可能会看到过某些请求的响应码是 304
,这个是告诉浏览器可以使用本地缓存的资源,通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存。
协商缓存就是与服务端协商之后,通过协商结果来判断是否使用本地缓存。
响应头部中 Etag:唯一标识响应资源; 请求头部中的 If-None-Match:当资源过期时,浏览器发现响应头里有 Etag,则再次向服务器发起请求时,会将请求头If-None-Match 值设置为 Etag 的值。服务器收到请求后进行比对,如果资源没有变化返回 304,如果资源变化了返回 200。 使用 ETag 字段实现的协商缓存的过程如下; 1.当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 ETag 唯一标识,这个唯一标识的值是根据当前请求的资源生成的; 2.当浏览器再次请求访问服务器中的该资源时,首先会先检查强制缓存是否过期,如果没有过期,则直接使用本地缓存;如果缓存过期了,会在 Request 头部加上 If-None-Match 字段,该字段的值就是 ETag 唯一标识; 3.服务器再次收到请求后,会根据请求中的 If-None-Match 值与当前请求的资源生成的唯一标识进行比较: 如果值相等,则返回 304 Not Modified,不会返回资源; 如果不相等,则返回 200 状态码和返回资源,并在 Response 头部加上新的 ETag 唯一标识; 4.如果浏览器收到 304 的请求响应状态码,则会从本地缓存中加载资源,否则更新资源。
GET与POST的区别?
GET请求:
浏览器地址栏中的地址是:action 属性[+?+请求参数] 请求参数的格式是:name=value&name=value
POST请求:
GET一般用于从服务器获取资源,而POST一般用于表单提交,有可能改变服务器上的资源;
请求形式上:GET请求的数据附在URL之后;POST请求的数据在请求体中;
安全性:GET请求可被缓存、收藏、保留到历史记录,且其请求数据明文出现在URL中。POST的参数不会被保存,安全性相对较高;
GET只允许ASCII字符(因为URL只支持ASCII字符),POST对数据类型没有要求,也允许二进制数据;
GET的长度有限制(操作系统或者浏览器),而POST数据大小无限制
GET是幂等的,即读取同一个资源,总是得到相同的数据,POST不是幂等的;
因为get是只读操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。 可以对GET请求的数据做缓存,这个缓存可以做到浏览器本身上,也可以做到代理上(如nginx),而且在浏览器中GET请求可以保存为书签。 POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。 所以,浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签。
响应的HTTP协议格式
HTTP/1.1的性能如何?
基于TCP/IP,使用请求-应答通信模式,所以关键在于这两点。
1、长连接:不需要每次发送请求都TCP连接,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。(如果超过一定时间没有任何数据交互,服务器回主动断开)
2、管道网络传输:在长连接基础上,同一个TCp连接,可以发送多个请求,不需要等上一个请求回来,就可以发送第二个,减少整体响应时间。服务器必须按照接收请求的顺序发送对这些管道化请求的响应。(有这个,但是浏览器都不支持基本)
3、队头阻塞:顺序发送的请求,由于某种原因阻塞了,后面排队的请求也同样阻塞。
HTTP/0.9 仅支持GET请求,不支持请求头
HTTP/1.0 默认短连接(一次请求建议一次TCP连接,请求完就断开),支持GET、POST、HEAD请求
HTTP/1.1:支持PUT、DELETE、PATCH等六种请求 增加host头,支持虚拟主机;支持断点续传功能
使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。
支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。
存在性能瓶颈:
请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body
的部分;
发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;
没有请求优先级控制;
请求只能从客户端开始,服务器只能被动响应。
HTTP/2.0 :是基于 HTTPS的
相比http/1.1性能上的改进:
头部压缩
如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分。
这就是所谓的 HPACK
算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
解析基于二进制格式
HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(Headers Frame)和数据帧(Data Frame)。
数据流
HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。
多路复用
HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应。移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率。
在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应A请求剩下的部分。
服务器主动推送(相关资源一个请求全部推送)
HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务端不再是被动地响应,可以主动向客户端发送消息。
缺陷:
HTTP/2 通过 Stream 的并发能力,解决了 HTTP/1 队头阻塞的问题,看似很完美了,但是 HTTP/2 还是存在“队头阻塞”的问题,只不过问题不是在 HTTP 这一层面,而是在 TCP 这一层。
HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题。
一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。
HTTP/3.0:
HTTP/1.1 和 HTTP/2 都有队头阻塞的问题:
HTTP/1.1 中的管道( pipeline)虽然解决了请求的队头阻塞,但是没有解决响应的队头阻塞,因为服务端需要按顺序响应收到的请求,如果服务端处理某个请求消耗的时间比较长,那么只能等响应完这个请求后, 才能处理下一个请求,这属于 HTTP 层队头阻塞。
HTTP/2 虽然通过多个请求复用一个 TCP 连接解决了 HTTP 的队头阻塞 ,但是一旦发生丢包,就会阻塞住所有的 HTTP 请求,这属于 TCP 层队头阻塞。
HTTP/2 队头阻塞的问题是因为 TCP,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!
UDP 发送是不管顺序,也不管丢包的,所以不会出现像 HTTP/2 队头阻塞的问题。大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。
QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP。所以,HTTP/3 现在普及的进度非常的缓慢。
HTTP/1.1如何优化?
尽量避免发送 HTTP 请求; 在需要发送 HTTP 请求时,考虑如何减少请求次数; 减少服务器的 HTTP 响应的数据大小;
1、尽量避免发送HTTP请求
将具有重复性的HTTP请求,【请求-响应】数据缓存到本地。
2、减少HTTP请求次数
减少重定向请求次数; 重定向的工作交由代理服务器完成,就能减少 HTTP 请求次数了 合并请求; 多个访问小文件的请求合并成一个大的请求。(当大资源中的某一个小资源发生变化后,客户端必须重新下载整个完整的大资源文 件,这显然带来了额外的网络消耗。) 延迟发送请求; 请求网页的时候,没必要把全部资源都获取到,而是只获取当前用户所看到的页面资源,当用户向下滑动页面的时候,再向服务器获取接下来的资源,这样就达到了延迟发送请求的效果。
如何减少 HTTP 响应的数据大小?
有损压缩和无损压缩
无损压缩
无损压缩是指资源经过压缩后,信息不被破坏,还能完全恢复到压缩前的原样,适合用在文本文件、程序可执行文件、程序源代码。
gzip 就是比较常见的无损压缩。所以如果可以,服务器应该选择压缩效率更高的 br 压缩算法。
有损压缩
解压的数据会与原始数据不同但是非常接近。
有损压缩主要将次要的数据舍弃,牺牲一些质量来减少数据量、提高压缩比,这种方法经常用于压缩多媒体数据,比如音频、视频、图片。
HTTPS在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。TLS使用对称加密和非对称加密的混合加密方式来实现机密性。
端口不同:HTTP使用的是80端口,HTTPS使用443端口;
HTTP(超文本传输协议)信息是明文传输,HTTPS运行在SSL(Secure Socket Layer)之上,添加了加密和认证机制,更加安全;
HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
HTTPS由于加密解密会带来更大的CPU和内存开销;
HTTPS 协议需要向 CA(证书权威机构)申请数字证书(需要购买),来保证服务器的身份是可信的。
HTTP的风险和HTTPS的应对(https解决了http啥问题)
http由于是明文传输,安全上存在三个风险:
窃听风险:比如通信链路上可以获取通信内容,用户号容易没。
篡改风险:比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
冒充风险:比如冒充淘宝网站,用户钱容易没。
https很好地解决了上述的风险:
信息加密:交互信息无法被窃取。 混合加密实现
校验机制:无法篡改通信内容,篡改了就不能正常显示。 摘要算法实现完整性,为数据生成指纹来校验。
身份证书:确定是真的网址,不能冒充。 把服务器公钥放入数字证书,解决冒充的风险。
1.混合加密: HTTPs采用的是对称加密和非对称加密结合的混合加密方式。 在通信建立前采用非对称加密交换会话密钥; 在通信过程中全部使用对称加密的会话密钥的方式加密明文数据。 - 对称加密:加密和解密采用相同的密钥。如:DES、RC2、RC4 - 非对称加密:需要两个密钥:公钥和私钥。两个密钥可以双向加解密。如:RSA 【公钥加密,私钥解密】保证内容传输的安全,因为只有私钥才能解密公钥加密的内容。 【私钥加密+公钥解密】保证消息不会冒充。因为私钥是不可泄漏的,如果公钥能揭秘成功,证明消息是持有私钥身份的人发送的。 采用混合加密的原因:对称加密只使用一个密钥,运算速度快,无法做到安全的交换;非对称使用两个密钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但是速度慢。所以综合两者。 2.摘要算法+数字签名: 为了保证传输的内容不被篡改,需要对内容计算出一个指纹,同内容一起传输给对方。对方收到后,会先对内容计算出一个指纹,跟发来的指纹比较,相同就说明内容没有被篡改。 使用摘要算法(哈希函数)来计算出内容的哈希值,也就是指纹。哈希值是唯一的,且无法通过哈希值推导出内容。摘要算法:MD5、SHA 通过哈希算法可以确保内容不会被篡改,但是不能保证【内容+哈希值】不会被中间人替换。 可以通过非对称加密的【私钥加密,公钥解密】的方式,来确认消息的身份。加密的是内容的哈希值。——数字签名(保证消息来源的可靠性) 发送者A用私钥进行签名,接收者B用公钥验证签名。因为除A外没有人有私钥,所以B相信签名是来自A。A不可抵赖,B也不能伪造报文。 私钥由服务端保管,服务端会向客户端颁发对应的公钥,如果客户端收到的消息,能被公钥解密,就说明消息是由服务器发送的。 3.数字证书: 公钥可能被伪造,通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。 数字证书认证机构--CA 服务器把自己的公钥注册到CA,CA用自己的私钥将服务器的公钥做数字签名并颁发数字证书。(数字证书 = 服务器的公钥+CA的数字签名) 客户端拿到服务器的数字证书后,使用CA的公钥确认服务器的数字证书的真实性。从数字证书获取服务器公钥。 客户端使用公钥对报文加密后发送,服务器用私钥对报文解密。
Https连接过程(SSL握手)
基本流程:客户端向服务器索要并验证服务器的公钥。双方协商生产会话密钥。双方采用会话密钥进行加密通信。
客户端向服务器发起加密通信请求,同时发送客户端支持的SSL/TLS协议版本,支持的一套加密规则。
服务器从中选出一组加密算法与HASH算法,并将自己的身份信息以数字证书的形式发回给客户端。证书里面包含了网站地址,加密公钥(用于非对称加密),以及证书的颁发机构等信息(证书中的私钥只能用于服务器端进行解密)。
客户端收到回应后,会先验证服务器的合法性,包括:证书是否过期,CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配;
如果证书受信任,客户端会生成一个随机密钥(用于对称算法),并用服务器提供的公钥加密(采用非对称算法对密钥加密);使用Hash算法对握手消息进行摘要计算,并对摘要使用之前产生的密钥加密(对称算法);将加密后的随机密钥和摘要一起发送给服务器;
服务器使用自己的私钥解密,得到对称加密的密钥,用这个密钥解密出Hash摘要值,并验证握手消息是否一致;如果一致,服务器使用对称加密的密钥加密握手消息发给客户端;
客户端解密并验证摘要,若一致,则握手结束。之后的数据传送都使用对称加密的密钥进行加密
总结:非对称加密算法用于在握手过程中加密生成的密码;对称加密算法用于对真正传输的数据进行加密;HASH算法(摘要算法)用于验证数据的完整性。数字签名保证消息来源的可靠性。
如何保证数据完整性?
TLS 在实现上分为握手协议和记录协议两层:
TLS 握手协议就是前面说的 TLS 四次握手的过程,负责协商加密算法和生成对称密钥,后续用此密钥来保护应用程序数据(即 HTTP 数据);
TLS 记录协议负责保护应用程序数据并验证其完整性和来源,所以对 HTTP 数据加密是使用记录协议;
TLS 记录协议主要负责消息(HTTP 数据)的压缩,加密及数据的认证。
首先,消息被分割成多个较短的消息片段,然后分别对每个片段进行压缩。
接下来,经过压缩的片段会被加上消息认证码(MAC 值,这个是通过哈希算法生成的),这是为了保证完整性,并进行数据的认证。通过附加消息认证码的 MAC 值,可以识别出篡改。与此同时,为了防止重放攻击,在计算消息认证码时,还加上了片段的编码。
再接下来,经过压缩的片段再加上消息认证码会一起通过对称密码进行加密。
最后,上述经过加密的数据再加上报头(由数据类型、版本号、压缩后的长度组成的)就是最终的报文数据。
记录协议完成后,最终的报文数据将传递到传输控制协议 (TCP) 层进行传输。
网站如何自动切换到 HTTPS
一种是原始的302跳转(临时重定向),服务器把所有的HTTp流量跳转到HTTPS。但这样有一个漏洞,就是第一次访问站点的时候如果是 HTTP 就有可能被中间人劫持,很可能都没到 302 跳转的时候就被劫持了。 解决方法是引入HSTS机制, 用户的浏览器一旦得到了 HSTS 的信息,下次再访问站点的时候客户端浏览器就会强制使用 HTTPS。 无论你在地址栏里输入什么,都会以 HTTPS 访问。
HSTS 本身也有缺陷,假如用户的浏览器从未访问过这个站点,那也就不会得到 HSTS 响应头, 这个时候依然会有被劫持风险, 但相比每次都进行服务端跳转的机制,已经好了不少。
针对 HSTS 的这个缺陷,主流的浏览器也提供了一些解决方案,比如把一些大流量并且已知支持 HSTS 的站点预先内置到浏览器中,这样就更大程度的完善了 HTTPS 的安全机制。
HTTPS 一定安全可靠吗?
客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服务器」,于是客户端是和「中间人服务器」完成了 TLS 握手,然后这个「中间人服务器」再与真正的服务端完成 TLS 握手。
从客户端的角度看,其实并不知道网络中存在中间人服务器这个角色。那么中间人就可以解开浏览器发起的 HTTPS 请求里的数据,也可以解开服务端响应给浏览器的 HTTPS 响应数据。相当于,中间人能够 “偷看” 浏览器与服务端之间的 HTTPS 请求和响应的数据。
但是要发生这种场景是有前提的,前提是用户点击接受了中间人服务器的证书。
中间人服务器与客户端在 TLS 握手过程中,实际上发送了自己伪造的证书给浏览器,而这个伪造的证书是能被浏览器(客户端)识别出是非法的,于是就会提醒用户该证书存在问题。
如果用户执意点击「继续浏览此网站」,相当于用户接受了中间人伪造的证书,那么后续整个 HTTPS 通信都能被中间人监听了。
这其实并不能说 HTTPS 不够安全,毕竟浏览器都已经提示证书有问题了。HTTPS 协议本身到目前为止还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是 HTTPS 不够安全
中间人攻击
HTTPS连接的时候,怎么确定收到的包是服务器发来的?
SSL劫持攻击 攻击者在传输过程中伪造服务器的证书,将服务器的公钥替换成自己的公钥; 但是对于客户端来说,如果中间人伪造了证书,在校验证书过程中会提示证书错误。 SSL剥离攻击 中间人和服务器之间仍然保持HTTPS服务器; 之后将HTTPS范文替换为HTTP返回给浏览器。
如何避免被中间人抓取数据?
要保证自己电脑的安全,不要被病毒乘虚而入,被恶意导入伪造的根证书。而且也不要点击任何证书非法的网站,这样 HTTPS 数据就不会被中间人截取到了。
当然,我们还可以通过 HTTPS 双向认证来避免这种问题。
一般我们的 HTTPS 是单向认证,客户端只会验证了服务端的身份,但是服务端并不会验证客户端的身份。
如果用了双向认证方式,不仅客户端会验证服务端的身份,而且服务端也会验证客户端的身份。服务端一旦验证到请求自己的客户端为不可信任的,服务端就拒绝继续通信,客户端如果发现服务端为不可信任的,那么也中止通信。
https RSA握手解析 & Ecdhe握手解析的区别
RSA 和 ECDHE 握手过程的区别: RSA 密钥协商算法「不支持」前向保密,ECDHE 密钥协商算法「支持」前向保密; 使用了 RSA 密钥协商算法,TLS 完成四次握手后,才能进行应用数据传输,而对于 ECDHE 算法,客户端可以不用等服务端的最后一次 TLS 握手,就可以提前发出加密的 HTTP 数据,节省了一个消息的往返时间(这个是 RFC 文档规定的,具体原因文档没有说明,所以这点我也不太明白); 使用 ECDHE, 在 TLS 第 2 次握手中,会出现服务器端发出的「Server Key Exchange」消息,而 RSA 握手过程没有该消息;
http如何优化
对于硬件优化的方向,因为 HTTPS 是属于计算密集型,应该选择计算力更强的 CPU,而且最好选择支持 AES-NI 特性的 CPU,这个特性可以在硬件级别优化 AES 对称加密算法,加快应用数据的加解密。 对于软件优化的方向,如果可以,把软件升级成较新的版本,比如将 Linux 内核 2.X 升级成 4.X,将 openssl 1.0.1 升级到 1.1.1,因为新版本的软件不仅会提供新的特性,而且还会修复老版本的问题。 对于协议优化的方向: 密钥交换算法应该选择 ECDHE 算法,而不用 RSA 算法,因为 ECDHE 算法具备前向安全性,而且客户端可以在第三次握手之后,就发送加密应用数据,节省了 1 RTT。 将 TLS1.2 升级 TLS1.3,因为 TLS1.3 的握手过程只需要 1 RTT,而且安全性更强。 对于证书优化的方向: 服务器应该选用 ECDSA 证书,而非 RSA 证书,因为在相同安全级别下,ECC 的密钥长度比 RSA 短很多,这样可以提高证书传输的效率; 服务器应该开启 OCSP Stapling 功能,由服务器预先获得 OCSP 的响应,并把响应结果缓存起来,这样 TLS 握手的时候就不用再访问 CA 服务器,减少了网络通信的开销,提高了证书验证的效率; 对于重连 HTTPS 时,我们可以使用一些技术让客户端和服务端使用上一次 HTTPS 连接使用的会话密钥,直接恢复会话,而不用再重新走完整的 TLS 握手过程。 常见的会话重用技术有 Session ID 和 Session Ticket,用了会话重用技术,当再次重连 HTTPS 时,只需要 1 RTT 就可以恢复会话。对于 TLS1.3 使用 Pre-shared Key 会话重用技术,只需要 0 RTT 就可以恢复会话。 这些会话重用技术虽然好用,但是存在一定的安全风险,它们不仅不具备前向安全,而且有重放攻击的风险,所以应当对会话密钥设定一个合理的过期时间。
WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。 WebSocket是需要浏览器和服务器握手进行建立连接的。而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。 WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。”
RPC(Remote Procedure Call)远程过程调用,它本身并不是一个具体的协议,而是一种调用方式。一种通过网络从远程计算机上请求服务,而不需要了解底层网络技术的协议。
RPC协议的主要目的是做到不同服务间调用方法像同一服务间调用本地方法一样。
如果仅仅是远程调用,还不算是RPC,因为RPC强调的是过程调用
,调用的过程对用户而言是应该是透明
的,用户不应该关心调用的细节,可以像调用本地服务一样调用远程服务。所以RPC一定要对调用的过程进行封装。
RPC的四个过程
1:建立通信 2:服务寻址 3:网络传输 4:服务调用
为什么要使用RPC
1:服务化/微服务 2:分布式系统架构 3:服务可重用 4:系统间交互调用
现在比较流行的RPC框架,都会采用TCP作为底层传输协议;广泛应用在大规模分布式应用中。
框架有哪些
RMI(远程方法调用)JAVA自带的远程方法调用工具;
Dubbo阿里开源的基于TCP的RPC框架,基于Netty的高性能RPC框架;
使用场景: 1)内部子系统较多。
众多的内部子系统是驱动采用RPC架构的原因之一,订单系统,支付系统,商品系统,用户系统............, 每个可独立单独布署。 RPC主要使用在大型企业内部子系统之间的调用。因为大型企业里面系统繁多,业务线复杂,而且效率优势非常重要的一块,这个时候RPC的优势就比较明显了。 基于HTTP协议的接口,包括Webservice等主要作为对外接口服务。
2)接口访问量巨大。
RPC基于长连接。 要求满足支持 "负载均衡",“熔断降级” 一类面向服务的高级特性。
3)接口非常多;
“服务发现”。
1、服务发现
HTTP中通过域名解析可以得到IP地址和端口号;
RPC中会有专门的中间服务去保存服务名和IP信息,比如consul或者etcd,甚至是redis。想要访问某个服务,就去这些中间服务去获得IP和端口信息。
2.底层连接形式
HTTP1.1协议为例,其默认在建立底层TCP连接之后会一直保持这个连接(keep alive),之后的请求和响应都会复用这条连接。
RPC协议,也是通过建立TCP长链接进行数据交互,但不同的地方在于,RPC协议一般还会再建个连接池,在请求量大的时候,建立多条连接放在池内。
由于连接池有利于提升网络请求性能,所以不少编程语言的网络库里都会给HTTP加个连接池,比如go就是这么干的。
3.传输的内容
RPC并没有规定数据传输格式,这个格式可以任意指定,不同的RPC协议,数据格式不一定相同;HTTP规定了网络传输的请求格式、响应格式。
Http中还定义了资源定位的路径,RPC中并不需要。
4、RPC需要满足像调用本地服务一样调用远程服务,也就是对调用过程在API层面进行封装;Http协议没有这样的要求,因此请求、响应等细节需要我们自己去实现。
上面说的HTTP,其实特指的是现在主流使用的HTTP1.1,HTTP2在前者的基础上做了很多改进,所以性能可能比很多RPC协议还要好。 由于 HTTP2 是2015年出来的。那时候很多公司内部的RPC协议都已经跑了好些年了,基于历史原因,一般也没必要去换了。
5、优缺点 (1)RPC方式更加透明,对用户更方便。Http方式更灵活,没有规定API和语言,跨语言、跨平台。 (2)RPC方式需要在API层面进行封装,限制了开发的语言环境。
(3)RPC主要使用在大型企业内部子系统之间的调用;HTTP协议主要作为对外接口服务。
(4)如果对效率要求更高,并且开发过程使用统一的技术栈,那么用RPC还是不错的。如果需要更加灵活,跨语言、跨平台,显然http更合适。
1.在架构上,RPC和MQ的差异点是,MQ有一个中间结点Message Queue,可以把消息存储。
2.同步调用:对于要立即等待返回处理结果的场景,RPC是首选。
3.MQ 的使用,一方面是基于性能的考虑,比如服务端不能快速的响应客户端(或客户端也不要求实时响应),需要在队列里缓存。另外一方面,它更侧重数据的传输,因此方式更加多样化,除了点对点外,还有订阅发布等功能。
4.而且随着业务增长,有的处理端处理量会成为瓶颈,会进行同步调用改造为异步调用,这个时候可以考虑使用MQ。
每个路由器维护一张表,记录该路由器到其它网络的”跳数“,路由器到与其直接连接的网络的跳数是1,每多经过一个路由器跳数就加1;更新该表时和相邻路由器交换路由信息;路由器允许一个路径最多包含15个路由器,如果跳数为16,则不可达。交付数据报时优先选取距离最短的路径。
(PS:RIP是应用层协议:RIP 协议到底是网络层协议,还是应用层的协议? - 知乎)
优缺点
实现简单,开销小
随着网络规模扩大开销也会增大;
最大距离为15,限制了网络的规模;
当网络出现故障时,要经过较长的时间才能将此信息传递到所有路由器
路由器仅根据网络号net-id来转发分组,当分组到达目的网络的路由器之后,再按照主机号host-id将分组交付给主机;同一网络上的所有主机的网络号相同。
从主机号host-id借用若干个比特作为子网号subnet-id;子网掩码:网络号和子网号都为1,主机号为0;数据报仍然先按照网络号找到目的网络,发送到路由器,路由器再按照网络号和子网号找到目的子网:将子网掩码与目标地址逐比特与操作,若结果为某个子网的网络地址,则送到该子网。
ARP协议完成了IP地址与物理地址的映射。每一个主机都设有一个 ARP 高速缓存,里面有所在的局域网上的各主机和路由器的 IP 地址到硬件地址的映射表。当源主机要发送数据包到目的主机时,会先检查自己的ARP高速缓存中有没有目的主机的MAC地址,如果有,就直接将数据包发到这个MAC地址,如果没有,就向所在的局域网发起一个ARP请求的广播包(在发送自己的 ARP 请求时,同时会带上自己的 IP 地址到硬件地址的映射),收到请求的主机检查自己的IP地址和目的主机的IP地址是否一致,如果一致,则先保存源主机的映射到自己的ARP缓存,然后给源主机发送一个ARP响应数据包。源主机收到响应数据包之后,先添加目的主机的IP地址与MAC地址的映射,再进行数据传送。如果源主机一直没有收到响应,表示ARP查询失败。
如果所要找的主机和源主机不在同一个局域网上,那么就要通过 ARP 找到一个位于本局域网上的某个路由器的硬件地址,然后把分组发送给这个路由器,让这个路由器把分组转发给下一个网络。剩下的工作就由下一个网络来做。
用于解决内网中的主机要和因特网上的主机通信。由NAT路由器将主机的本地IP地址转换为全球IP地址,分为静态转换(转换得到的全球IP地址固定不变)和动态NAT转换。
面试/笔试第一弹 —— 计算机网络面试问题集锦
什么时候选TCP、UDP?
TCP速率与窗口,带宽,RTT之间的关系