备战秋招,面试知识点总结:计算机网络(五)

 

TCP怎么保证可靠性

TCP保证可靠性:

(1)序列号、确认应答、超时重传

数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明了它下一次需要接收的数据序列号。如果发送发迟迟未收到确认应答,那么可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间)+一个偏差值。

如果发送端发送的某个报文丢了,则超时后重传一次。

如果接送段对发送端某个报文的确认丢了,则超时后重传,发送端重新发送该报文,接受端接受后立马丢弃,然后再次确认该报文。

如果接受端的确认迟到了,则超时后经历一段丢失情况的情形,然后迟到的报文到了发送端,此时发送端已经在重发后对该端确认过了,收到迟到报文后直接丢弃。

如果开启了快重传,则接受端每次接受到报文都马上回一个苛求所丢报文的回复,接收端收到三次后立即重传。

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

流量控制针对的是使接收端能来得及接受发送端的数据,而调整发送速度

拥塞控制是防止过多的数据注入到网络内

(2)窗口控制与高速重发控制/快速重传(重复确认应答)

TCP会利用窗口控制来提高传输速度,意思是在一个窗口大小内,不用一定要等到应答才能发送下一段数据,窗口大小就是无需等待确认而可以继续发送数据的最大值。如果不使用窗口控制,每一个没收到确认应答的数据都要重发。

使用窗口控制,如果数据段1001-2000丢失,后面数据每次传输,确认应答都会不停地发送序号为1001的应答,表示我要接收1001开始的数据,发送端如果收到3次相同应答,就会立刻进行重发;

(3)拥塞控制

如果把窗口定的很大,发送端连续发送大量的数据,可能会造成网络的拥堵(大家都在用网,你在这狂发,吞吐量就那么大,当然会堵),甚至造成网络的瘫痪。所以TCP在为了防止这种情况而进行了拥塞控制。

慢启动:定义拥塞窗口,一开始将该窗口大小设为1,之后每次收到确认应答(经过一个rtt),将拥塞窗口大小*2。

拥塞避免:设置慢启动阈值,一般开始都设为65536。拥塞避免是指当拥塞窗口大小达到这个阈值,拥塞窗口的值不再指数上升,而是加法增加(每次确认应答/每个rtt,拥塞窗口大小+1),以此来避免拥塞。

将报文段的超时重传看做拥塞,则一旦发生超时重传,我们需要先将阈值设为当前窗口大小的一半,并且将窗口大小设为初值1,然后重新进入慢启动过程。

快速重传:在遇到3次重复确认应答(高速重发控制)时,代表收到了3个报文段,但是这之前的1个段丢失了,便对它进行立即重传。

然后,先将阈值设为当前窗口大小的一半,然后将拥塞窗口大小设为慢启动阈值+3的大小。

快重传是为了防止发送端错误的认为发送了拥塞,因为只有在超时的情况下才会判断为拥塞,现在通过快重传在超时前就重传了数据段,如果接下来正常接收到确认,则的确没有发送拥塞,而如果超时了,则说明发生了拥塞。

快恢复:执行快重传后将阈值设为当前窗口大小的一半

这样可以达到:在TCP通信时,网络吞吐量呈现逐渐的上升,并且随着拥堵来降低吞吐量,再进入慢慢上升的过程,网络不会轻易的发生瘫痪。

TCP建立连接和断开连接的过程:

三次握手:

1. Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

2. Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

3. Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

 第二次握手实际上是统一了对对端第一次握手的确认和第三次(四次中的第三次)握手的发起,将四次精简到三次。

A端为什么要对第二次握手在进行确认:

现在假设没有这个确认,也就是只有两次握手,第一次A->B,第二次B->A

则现在假设A的第一个请求延误在网络中,超时后A再进行一次请求,并与B建立了连接。

然后交换完后A与B的连接断开,而断开后这个延误的请求达到了B。

则这样的情况下如果没有第三次的确认,则相当于A再次向B进行了一次请求,而B也马上将这个请求确认,两边因为一个延误的请求而建立起了连接。

对A来说,它是不想进行这次连接的,因此也不会向里写数据,只留B端留着这个套接字浪费资源。

因此第三次确认的作用就是用来防止这个延误的请求。

四次挥手:

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了即不会再收到数据了但是在这个TCP连接上仍然能够发送数据直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

1.数据传输结束后,客户端的应用进程发出连接释放报文段,并停止发送数据,客户端进入FIN_WAIT_1状态,此时客户端依然可以接收服务器发送来的数据。

2.服务器接收到FIN后,发送一个ACK给客户端,确认序号为收到的序号+1,服务器进入CLOSE_WAIT状态客户端收到后进入FIN_WAIT_2状态

3.当服务器没有数据要发送时,服务器发送一个FIN报文,此时服务器进入LAST_ACK状态,等待客户端的确认

4.客户端收到服务器的FIN报文后,给服务器发送一个ACK报文,确认序列号为收到的序号+1。此时客户端进入TIME_WAIT状态,等待2MSL(MSL:报文段最大生存时间),然后关闭连接。

为什么客户端要有TIME_WAIT状态,等待2MSL

1.为了防止A发送的最后一个ACK报文。最后一个ACK报文可能丢失,如果没有TIMEWAIT,而最后一个ACK也丢失,则无法收到B重传的FIN,也就使B无法关闭这个套接字。

2.为了防止延迟的报文。如果没有TIMEWAIT,则当A与另一个服务端建立连接后,这个报文才到来从而影响A。

IP地址:

IP地址分为网络号和主机号,一个IP地址有四个字节共32位:

网络号分为A,B,C三类:

A类有8位,首位为0用于与B,C类相区别,真正可用的只有7位,而网络号全0表示“本网络”,要去除,127(剩下的7位全1)表示本环回地址的网络号,因此网络号为127的根本不是一个网络地址,因此A类可用的网络号有126个,1~126.

B类有16位,前两位1 0用于区别A,C类,真正可用的有14位。由于首位是1,因此不可能出现前两个字节为全0,又因为第二位位为1,也不可能出现127,因此不用像A一样减去2个。而B中128.0.0.0(十四位全为0)不指派,因此最小是128.1.0.0(前八位为10000000,后八位为00000001)

C类有24位,共3个字节,前三位1 1 0用于区分A,B类,还剩21位。和B一样,192.0.0是不指派的(除110外全为0),因此其实网络号为192.0.1.

主机号:

主机号全为0表示本主机所连接到的网络地址,也就是这个网络的代表。

主机号全为1表示该网络上的所有主机,也就是对该网络进行广播的地址。

子网掩码:

引入子网的原因:

1.IP地址利用率低,如果一个单位申请了一个B类网络,但主机数量C类就能满足,则可以在不用重新申请一个C类的情况下,将B类通过子网进行划分,用于以后的发展。

2.给每一个物理网络分配一个网络号会使路由表太大。

3.2级地址不够灵活:如果开通了一个新网络,在申请新的IP之前,利用子网来增加一个新的物理网络。

增加子网之后,网络以外的其他网络看不见子网,对外表现为同一个网络,只有对内才表现出不同的物理网络。

子网用于对本网络进行划分,通过在主机号段拿一部分作为子网号,把二级地址划分为三级地址。

子网掩码:

用目的IP地址与子网掩码按位与,就能得到目的所处的子网的网络号。

子网增加了灵活性,但减少了所能连结的主机数量。

ARP协议

为了通过网络层使用的IP地址,解析出在数据链路层使用的硬件地址。因此也被归到了网络层。

在传输过程中,IP地址始终保持不变,而MAC地址因为处在链路层所以随着链路改变而改变。

每个主机都有一个 ARP 高速缓存,里面有本局域网上的各主机和路由器的 IP 地址到 MAC 地址的映射表。 如果主机 A 知道主机 B 的 IP 地址,但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射,此时主机 A 通过广播 的方式发送 ARP 请求分组,主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址,随后主机 A 向其 高速缓存中写入主机 B 的 IP 地址到 MAC 地址的映射。

网际控制报文协议(ICMP)

ICMP 是为了更有效地转发 IP 数据报和提高交付成功的机会。它封装在 IP 数据报中,但是不属于高层协议。

1. Ping Ping 是 ICMP 的一个重要应用,主要用来测试两台主机之间的连通性。

Ping 的原理是通过向目的主机发送 ICMP Echo 请求报文,目的主机收到之后会发送 Echo 回答报文。Ping 会根据时 间和成功响应的次数估算出数据包往返时间以及丢包率。

2. Traceroute Traceroute 是 ICMP 的另一个应用,用来跟踪一个分组从源点到终点的路径。

Traceroute 发送的 IP 数据报封装的是无法交付的 UDP 用户数据报,并由目的主机发送终点不可达差错报告报文。

源主机向目的主机发送一连串的 IP 数据报。第一个数据报 P1 的生存时间 TTL 设置为 1,当 P1 到达路径上的第 一个路由器 R1 时,R1 收下它并把 TTL 减 1,此时 TTL 等于 0,R1 就把 P1 丢弃,并向源主机发送一个 ICMP 时间超过差错报告报文; 源主机接着发送第二个数据报 P2,并把 TTL 设置为 2。P2 先到达 R1,R1 收下后把 TTL 减 1 再转发给 R2,R2 收下后也把 TTL 减 1,由于此时 TTL 等于 0,R2 就丢弃 P2,并向源主机发送一个 ICMP 时间超过差错报文。 不断执行这样的步骤,直到最后一个数据报刚刚到达目的主机,主机不转发数据报,也不把 TTL 值减 1。但是 因为数据报封装的是无法交付的 UDP,因此目的主机要向源主机发送 ICMP 终点不可达差错报告报文。 之后源主机知道了到达目的主机所经过的路由器 IP 地址以及到达每个路由器的往返时间。

路由器分组转发流程

从数据报的首部提取目的主机的 IP 地址 D,得到目的网络地址 N。

若 N 就是与此路由器直接相连的某个网络地址,则进行直接交付;

若路由表中有目的地址为 D 的特定主机路由,则把数据报传送给表中所指明的下一跳路由器;

若路由表中有到达网络 N 的路由,则把数据报传送给路由表中所指明的下一跳路由器;

若路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器; 报告转发分组出错。

路由选择协议:更新路由器到各地点的路线

互联网可以划分为许多较小的自治系统 AS,一个 AS 可以使用一种和别的 AS 不同的路由选择协议。

可以把路由选择协议划分为两大类:

自治系统内部的路由选择:RIP 和 OSPF

自治系统间的路由选择:BGP

自洽系统代表使用同一种技术管理的路由器合集,对其他AS,本AS表现为一个单一和一致的路由器选择策略

1. 内部网关协议 RIP(基于距离向量的路由选择协议)

本路由器到直接相连的网络的距离定义为1(因为要交付)。到非直接相连的网络的距离为到达该网络所经过的路由器+1,+1是因为要交付。

距离是指跳数,直接相连的路由器跳数为 1。跳数最多为 15,超过 15 表 示不可达。

RIP 按固定的时间间隔仅和相邻路由器交换自己的路由表,经过若干次交换之后,所有路由器最终会知道到达本自治 系统中任何一个网络的最短距离和下一跳路由器地址。

距离向量算法:找到道每个目的网络的最短距离,用于更新路由表

对地址为 X 的相邻路由器发来的 RIP 报文,先修改报文中的所有项目,把下一跳字段中的地址改为 X,并把所 有的距离字段加 1(因为要调到X);

对修改后的 RIP 报文中的每一个项目,进行以下步骤:

若原来的路由表中没有目的网络 N,则把该项目添加到路由表中;

否则:若下一跳路由器地址是 X,则把收到的项目替换原来路由表中的项目;

否则:若收到的项目中的距离 d 小于路由表中的距离,则进行更新(例如原始路由表项为 Net2, 5, P,新表项为 Net2, 4, X,则更新);

否则什 么也不做。

若 3 分钟还没有收到相邻路由器的更新路由表,则把该相邻路由器标为不可达,即把距离置为 16。

RIP 协议实现简单,开销小。但是 RIP 能使用的最大距离为 15,限制了网络的规模。并且当网络出现故障时,要经过比较长的时间才能将此消息传送到所有路由器。

2. 内部网关协议 OSPF:开放最短路径优先 OSPF

开放最短路径优先 OSPF,是为了克服 RIP 的缺点而开发出来的。

开放表示 OSPF 不受某一家厂商控制,而是公开发表的;最短路径优先表示使用了 Dijkstra 提出的最短路径算法 SPF

OSPF 具有以下特点: 向本自治系统中的所有路由器发送信息,这种方法是洪泛法。

发送的信息就是与相邻路由器的链路状态,链路状态包括与哪些路由器相连以及链路的度量,度量用费用、距 离、时延、带宽等来表示。

只有当链路状态发生变化时,路由器才会发送信息。

所有路由器都具有全网的拓扑结构图,并且是一致的。相比于 RIP,OSPF 的更新过程收敛的很快。

3. 外部网关协议 BGP:用于不同的自洽系统间。

BGP(Border Gateway Protocol,边界网关协议)
AS 之间的路由选择很困难,主要是由于:
互联网规模很大;
各个 AS 内部使用不同的路由选择协议,无法准确定义路径的度量;
AS 之间的路由选择必须考虑有关的策略,比如有些 AS 不愿意让其它 AS 经过。
BGP 只能寻找一条比较好的路由,而不是最佳路由。

每个 AS 都必须配置 BGP 发言人,通过在两个相邻 BGP 发言人之间建立 TCP 连接来交换路由信息。

DNS:域名系统

用于将域名转换为IP地址。

DNS 可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。大多数情况下 DNS 使用 UDP 进行传输,这就要求
域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。在两种情况下会使用 TCP 进行传输:
如果返回的响应超过的 512 字节(UDP 最大只支持 512 字节的数据)。
区域传送(区域传送是主域名服务器向辅助域名服务器传送变化的那部分数据)。

DNS查询:

1).递归查询:

当本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器向根域名服务器查询,根服务器再向其他域名服务器进行递归查询,在得到IP地址后返回给本地域名服务器,再由本地域名服务器返回给主机。

2).迭代查询:

当本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器向根域名服务器进行查询,根域名服务器要么给出答案,要么告诉本地域名服务器应该向哪个顶级域名服务器询问。本地域名服务器向指定顶级域名服务器查询后,要么得到答案,要么再向某个权限域名服务器进行请求,直到得到答案并返回给主机。

递归查询,每一次查询,被查询服务器都以DNS客户的身份向另一个服务器进行查询,就像压栈一样,得到答案后一层层返回弹栈。

迭代查询,每一次查询,都是由本地域名服务器向某个服务器发起。

主机向本地域名服务器的一定是递归查询,因为本地域名服务器一定是以DNS客户的身份去请求答案。

而本地域名服务器向其他服务器请求,可以是递归查询,也可以是迭代查询。

文件传送协议FTP

FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件:

控制连接:服务器打开端口号 21 等待客户端的连接,客户端主动建立连接后,使用这个连接将客户端的命令传 送给服务器,并传回服务器的应答。(此进程用于接收客户端请求,传送数据使用数据连接)

数据连接:用来传送一个文件数据。

根据数据连接是否是服务器端主动建立,FTP 有主动和被动两种模式:

主动模式:服务器端主动建立数据连接,其中服务器端的端口号为 20,客户端的端口号随机,但是必须大于 1024,因为 0~1023 是熟知端口号。

被动模式:客户端主动建立数据连接,其中客户端的端口号由客户端自己指定,服务器端的端口号随机。

主动模式要求客户端开放端口号给服务器端,需要去配置客户端的防火墙。被动模式只需要服务器端开放端口号即可,无需客户端配置防火墙。但是被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。

动态主机配置协议

DHCP (Dynamic Host Configuration Protocol) 提供了即插即用的连网方式,用户不再需要手动配置 IP 地址等信 息。

DHCP 配置的内容不仅是 IP 地址,还包括子网掩码、网关 IP 地址

DHCP 工作过程如下:

1. 客户端发送 Discover 报文,该报文的目的地址为 255.255.255.255:67,源地址为 0.0.0.0:68,被放入 UDP 中,该报文被广播到同一个子网的所有主机上。如果客户端和 DHCP 服务器不在同一个子网,就需要使用中继代理

2. DHCP 服务器收到 Discover 报文之后,发送 Offer 报文给客户端,该报文包含了客户端所需要的信息。因为客户端可能收到多个 DHCP 服务器提供的信息,因此客户端需要进行选择。

3. 如果客户端选择了某个 DHCP 服务器提供的信息,那么就发送 Request 报文给该 DHCP 服务器。

4. DHCP 服务器发送 Ack 报文,表示客户端此时可以使用提供给它的信息。

Discover用于寻找DHCP

Offer用于提供IP及所需信息

Request用于正式申请

Ack为同意申请

远程登录协议

TELNET 用于登录到远程主机上,并且远程主机上的输出也会返回。
TELNET 可以适应许多计算机和操作系统的差异,例如不同操作系统系统的换行符定义。

电子邮件协议

一个电子邮件系统由三部分组成:用户代理、邮件服务器以及邮件协议。
邮件协议包含发送协议读取协议发送协议常用 SMTP读取协议常用 POP3IMAP

1. SMTP SMTP 只能发送 ASCII 码,而互联网邮件扩充 MIME 可以发送二进制文件。MIME 并没有改动或者取代 SMTP,而是 增加邮件主体的结构,定义了非 ASCII 码的编码规则。

2.POP3
POP3 的特点是只要用户从服务器上读取了邮件,就把该邮件删除。
3. IMAP
IMAP 协议中客户端和服务器上的邮件保持同步,如果不手动删除邮件,那么服务器上的邮件也不会被删除。IMAP这种做法可以让用户随时随地去访问服务器上的邮件。

常用协议及端口

Web 页面请求过程

1).DHCP 配置主机信息
假设主机最开始没有 IP 地址以及其它信息,那么就需要先使用 DHCP 来获取。
主机生成一个 DHCP 请求报文,并将这个报文放入具有目的端口 67 和源端口 68 的 UDP 报文段中。该报文段则被放入在一个具有广播 IP 目的地址(255.255.255.255) 和源 IP 地址(0.0.0.0)的 IP 数据报中。
该数据报则被放置在 MAC 帧中,该帧具有目的地址 FF:FF:FF:FF:FF:FF,将广播到与交换机连接的所有设备。
连接在交换机的 DHCP 服务器收到广播帧之后,不断地向上分解得到 IP 数据报、UDP 报文段、DHCP 请求报文,之后生成 DHCP ACK 报文,该报文包含以下信息:IP 地址、DNS 服务器的 IP 地址、默认网关路由器的 IP地址和子网掩码。该报文被放入 UDP 报文段中,UDP 报文段有被放入 IP 数据报中,最后放入 MAC 帧中。
该帧的目的地址是请求主机的 MAC 地址,因为交换机具有自学习能力,之前主机发送了广播帧之后就记录了MAC 地址到其转发接口的交换表项因此现在交换机就可以直接知道应该向哪个接口发送该帧(因为虽然IP地址还没分配下来,但MAC地址已经知道了)
主机收到该帧后,不断分解得到 DHCP 报文。之后就配置它的 IP 地址、子网掩码和 DNS 服务器的 IP 地址,并
在其 IP 转发表中安装默认网关。

2. ARP 解析 MAC 地址

主机通过浏览器生成一个 TCP 套接字,套接字向 HTTP 服务器发送 HTTP 请求。为了生成该套接字,主机需要 知道网站的域名对应的 IP 地址

主机生成一个 DNS 查询报文,该报文具有 53 号端口,因为 DNS 服务器的端口号是 53。

该 DNS 查询报文被放入目的地址为 DNS 服务器 IP 地址的 IP 数据报中。

该 IP 数据报被放入一个以太网帧中,该帧将发送到网关路由器。

DHCP 过程只知道网关路由器的 IP 地址,为了获取网关路由器的 MAC 地址,需要使用 ARP 协议。

主机生成一个包含目的地址为网关路由器 IP 地址的 ARP 查询报文,将该 ARP 查询报文放入一个具有广播目的 地址(FF:FF:FF:FF:FF:FF)的以太网帧中,并向交换机发送该以太网帧,交换机将该帧转发给所有的连接设备, 包括网关路由器。

网关路由器接收到该帧后,不断向上分解得到 ARP 报文,发现其中的 IP 地址与其接口的 IP 地址匹配,因此就 发送一个 ARP 回答报文,包含了它的 MAC 地址,发回给主机(单播)。

3. DNS 解析域名

知道了网关路由器的 MAC 地址之后,就可以继续 DNS 的解析过程了。

网关路由器接收到包含 DNS 查询报文的以太网帧后,抽取出 IP 数据报,并根据转发表决定该 IP 数据报应该转 发的路由器。

因为路由器具有内部网关协议(RIP、OSPF)和外部网关协议(BGP)这两种路由选择协议,因此路由表中已 经配置了网关路由器到达 DNS 服务器的路由表项。

到达 DNS 服务器之后,DNS 服务器抽取出 DNS 查询报文,并在 DNS 数据库中查找待解析的域名。

找到 DNS 记录之后,发送 DNS 回答报文,将该回答报文放入 UDP报文段中,然后放入 IP 数据报中,通过路 由器反向转发回网关路由器,并经过以太网交换机到达主机。

4. HTTP 请求页面

有了 HTTP 服务器的 IP 地址之后,主机就能够生成 TCP 套接字,该套接字将用于向 Web 服务器发送 HTTP GET 报文。

在生成 TCP 套接字之前,必须先与 HTTP 服务器进行三次握手来建立连接。生成一个具有目的端口 80 的 TCP SYN 报文段,并向 HTTP 服务器发送该报文段。

HTTP 服务器收到该报文段之后,生成 TCP SYN ACK 报文段,发回给主机。

连接建立之后,浏览器生成 HTTP GET 报文,并交付给 HTTP 服务器。

HTTP 服务器从 TCP 套接字读取 HTTP GET 报文,生成一个 HTTP 响应报文,将 Web 页面内容放入报文主体 中,发回给主机。

浏览器收到 HTTP 响应报文后,抽取出 Web 页面内容,之后进行渲染,显示 Web 页面。

HTTP 方法

1,GET:GET可以说是最常见的了,它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。

2,HEAD:HEAD和GET本质是一样的,区别在于HEAD不含有呈现数据,而仅仅是HTTP头信息。有的人可能觉得这个方法没什么用,其实不是这样的。想象一个业务情景:欲判断某个资源是否存在,我们通常使用GET,但这里用HEAD则意义更加明确。

3,PUT:这个方法比较少见。HTML表单也不支持这个。本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有一个重要区别,PUT通常指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器自己决定。
举个例子:如一个用于提交博文的URL,/addBlog。如果用PUT,则提交的URL会是像这样的”/addBlog/abc123”,其中abc123就是这个博文的地址。而如果用POST,则这个地址会在提交后由服务器告知客户端。目前大部分博客都是这样的。显然,PUT和POST用途是不一样的。具体用哪个还取决于当前的业务场景。

4,DELETE:删除某一个资源。基本上这个也很少见,不过还是有一些地方比如amazon的S3云服务里面就用的这个方法来删除资源。

5,POST:向服务器提交数据。这个方法用途广泛,几乎目前所有的提交操作都是靠这个完成。

6,OPTIONS:这个方法很有趣,但极少使用。它用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。

HTTP 状态码:

1XX 信息
100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。

2XX 成功
200 OK
204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端
往服务器发送信息,而不需要返回数据时使用。
206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。

3XX 重定向
301 Moved Permanently :永久性重定向
302 Found :临时性重定向
303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。
注:虽然 HTTP 协议规定 301、302 状态下重定向时不允许把 POST 方法改成 GET 方法,但是大多数浏览器都
会在 301、302 和 303 状态下的重定向把 POST 方法改成 GET 方法。
304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-
Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。
307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的
POST 方法改成 GET 方法。

4XX 客户端错误
400 Bad Request :请求报文中存在语法错误。
401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进
行过一次请求,则表示用户认证失败。
403 Forbidden :请求被拒绝。
404 Not Found

5XX 服务器错误
500 Internal Server Error :服务器正在执行请求时发生错误。
503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

HTTP连接管理:

1. 短连接与长连接

当浏览器访问一个包含多张图片的 HTML 页面时,除了请求访问的 HTML 页面资源,还会请求图片资源。如果每进 行一次 HTTP 通信就要新建一个 TCP 连接,那么开销会很大。

长连接只需要建立一次 TCP 连接就能进行多次 HTTP 通信。

从 HTTP/1.1 开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用 Connection : close ; 在 HTTP/1.1 之前默认是短连接的,如果需要使用长连接,则使用 Connection : Keep-Alive 。

2. 流水线 默认情况下,HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到响应之后才会被发出。由于受到网络延迟 和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。 流水线是在同一条长连接上连续发出请求,而不用等待响应返回,这样可以减少延迟。

Cookie和Session

HTTP 协议是无状态的,主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务。HTTP/1.1 引入 Cookie 来
保存状态信息。

Cookie:
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被
携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来
额外的性能开销(尤其是在移动环境下)。

1. 用途
会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
个性化设置(如用户自定义设置、主题等)
浏览器行为跟踪(如跟踪分析用户行为等)

2. 创建过程
服务器发送的响应报文包含 Set-Cookie 首部字段,客户端得到响应报文后把 Cookie 内容保存到浏览器中。

Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

客户端之后对同一个服务器发送请求时,会从浏览器中取出 Cookie 信息并通过 Cookie 请求首部字段发送给服务
器。

Cookie: yummy_cookie=choco; tasty_cookie=strawberry

3. 分类
会话期 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。
持久性 Cookie:指定过期时间(Expires)或有效期(max-age)之后就成为了持久性的 Cookie。

Session:
除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信
息更加安全。
Session 可以存储在服务器上的文件、数据库或者内存中。也可以将 Session 存储在 Redis 这种内存型数据库中,效
率会更高。
使用 Session 维护用户登录状态的过程如下:
用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
服务器验证该用户名和密码,如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;
服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie
值存入浏览器中;
客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取
出用户信息,继续之前的业务操作
应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session
ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下,例如转账等操作,除了使用 Session
管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。

浏览器禁用 Cookie 此时无法使用 Cookie 来保存用户信息,只能使用 Session。除此之外,不能再将 Session ID 存放到 Cookie 中,而 是使用 URL 重写技术,将 Session ID 作为 URL 的参数进行传递。

Cookie 与 Session 选择
Cookie 只能存储 ASCII 码字符串而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选
Session;
Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加
密,然后在服务器进行解密;
对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信
息都存储到 Session 中。

HTTPS:

HTTP 有以下安全性问题:
使用明文进行通信,内容可能会被窃听;
不验证通信方的身份,通信方的身份有可能遭遇伪装;
无法证明报文的完整性,报文有可能遭篡改。

HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是说HTTPS 使用了隧道进行通信。

通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。

加密:

1. 对称密钥加密
对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥
优点:运算速度快;
缺点:无法安全地将密钥传输给通信方。

2.非对称密钥加密
非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥
公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通
信内容后使用私有密钥解密
非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥
进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。
优点:可以更安全地将公开密钥传输给通信发送方;
缺点:运算速度慢。

HTTPS 采用的加密方式
HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥
加密进行通信来保证通信过程的效率。(下图中的 Session Key 就是对称密钥)

首先客户端请求连接

服务器将一个非对称加密的公开密钥传递给客户端,客户端使用这个公开密钥对对称密钥进行加密,加密后传给服务器端

服务器端用非对称加密的私有密钥进行解锁,解锁后得到了客户端发送的对称密钥

以后两端的通信都通过这个对称密钥来进行通信。

这样的方式能避免对称密钥被窃取。

认证:
通过使用 证书 来对通信方进行认证。
数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。
服务器的运营人员向 CA 提出公开密钥的申请,CA 在判明提出申请者的身份之后,会对已申请的公开密钥做数字签
名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。
进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,
如果验证通过,就可以开始通信了。

认证过程:

1. 客户端发起HTTPS请求

这个没什么好说的,就是用户在浏览器里输入一个https网址,然后连接到server的443端口。

2. 服务端的配置

采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。这套证书其实就是一对公钥和私钥。如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

3. 传送证书

这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。

4. 客户端解析证书

这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值。然后用证书对该随机值进行加密。就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。

5. 传送加密信息

这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了

6. 服务段解密信息

服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。

7. 传输加密后的信息

这部分信息是服务段用私钥加密后的信息,可以在客户端被还原

8. 客户端解密信息

客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策。

完整性保护
SSL 提供报文摘要功能来进行完整性保护。
HTTP 也提供了 MD5 报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算 MD5 的值,通信接
收方是无法意识到发生了篡改。
HTTPS 的报文摘要功能之所以安全,是因为它结合了加密和认证这两个操作。试想一下,加密之后的报文,遭到篡
改之后,也很难重新计算报文摘要,因为无法轻易获取明文。
HTTPS 的缺点
因为需要进行加密解密等过程,因此速度会更慢;
需要支付证书授权的高额费用。

HTTP2.0

HTTP/1.x 缺陷
HTTP/1.x 实现简单是以牺牲性能为代价的:
客户端需要使用多个连接才能实现并发和缩短延迟
不会压缩请求和响应首部,从而导致不必要的网络流量;
不支持有效的资源优先级,致使底层 TCP 连接的利用率低下。

HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式的。

在通信过程中,只会有一个 TCP 连接存在,它承载了任意数量的双向数据流(Stream)。
一个数据流(Stream)都有一个唯一标识符可选的优先级信息,用于承载双向信息。
消息(Message)是与逻辑请求或响应对应的完整的一系列帧
帧(Frame)是最小的通信单位,来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重
新组装。

服务端推送
HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客
户端请求 page.html 页面,服务端就把 script.js 和 style.css 等与之相关的资源一起发给客户端。

首部压缩
HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。
HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见过的首部字段表,从而避免了重复传输。
不仅如此,HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。

GET 和 POST 比较

https://www.cnblogs.com/snowwhite/p/4640740.html

作用
GET 用于获取资源,而 POST 用于传输实体主体

参数
GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在
实体主体中。不能因为 POST 参数存储在实体主体中就认为它的安全性更高,因为照样可以通过一些抓包工具
(Fiddler)查看。

因为 URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码。例如 中文 会转换为
%E4%B8%AD%E6%96%87 ,而空格会转换为 %20 。POST 参数支持标准字符集

下图中,GET中参数出现在URL里,而POST放在实体主体里。

安全
安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。
GET 方法是安全的,而 POST 却不是,因为 POST 的目的是传送实体主体内容,这个内容可能是用户上传的表单数
据,上传成功之后,服务器可能把这个数据存储到数据库中,因此状态也就发生了改变。
安全的方法除了 GET 之外还有:HEAD、OPTIONS。
不安全的方法除了 POST 之外还有 PUT、DELETE。

幂等性
幂等的 HTTP 方法,同样的请求被执行一次与连续执行多次的效果是一样的服务器的状态也是一样的。换句话说就
是,幂等方法不应该具有副作用(统计用途除外)。
所有的安全方法也都是幂等的。
在正确实现的条件下,GET,HEAD,PUT 和 DELETE 等方法都是幂等的,而 POST 方法不是。

可缓存
如果要对响应进行缓存,需要满足以下条件:
请求报文的 HTTP 方法本身是可缓存的,包括 GET 和 HEAD,但是 PUT 和 DELETE 不可缓存,POST 在多数情
况下不可缓存的。
响应报文的状态码是可缓存的,包括:200, 203, 204, 206, 300, 301, 404, 405, 410, 414, and 501。
响应报文的 Cache-Control 首部字段没有指定不进行缓存。

Select,poll与epoll

select:

有三种类型的描述符类型:readset、writeset、exceptset,分别对应读、写、异常条件的描述符集合。fd_set 使用
数组实现,数组大小使用 FD_SETSIZE 定义。
timeout 为超时参数,调用 select 会一直阻塞直到有描述符的事件到达或者等待的时间超过 timeout。
成功调用返回结果大于 0,出错返回结果为 -1,超时返回结果为 0。

poll:

pollfd 使用链表实现。

select与epoll的比较:

比较
1. 功能
select 和 poll 的功能基本相同,不过在一些实现细节上有所不同。
select 会修改描述符,而 poll 不会(当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。);
select 的描述符类型使用数组实现,FD_SETSIZE 大小默认为 1024,因此默认只能监听 1024 个描述符。如果
要监听更多描述符的话,需要修改 FD_SETSIZE 之后重新编译;而 poll 的描述符类型使用链表实现,没有描述
符数量的限制;
poll 提供了更多的事件类型,并且对描述符的重复利用上比 select 高。
如果一个线程对某个描述符调用了 select 或者 poll,另一个线程关闭了该描述符,会导致调用结果不确定。

2. 速度
select 和 poll 速度都比较慢。
select 和 poll 每次调用都需要将全部描述符从应用进程缓冲区复制到内核缓冲区(而epoll不用)。
select 和 poll 的返回结果中没有声明哪些描述符已经准备好,所以如果返回值大于 0 时,应用进程都需要使用
轮询的方式来找到 I/O 完成的描述符。
3. 可移植性
几乎所有的系统都支持 select,但是只有比较新的系统支持 poll。

epoll:

epoll_ctl() 用于向内核注册新的描述符或者是改变某个文件描述符的状态。已注册的描述符在内核中会被维护在一棵
红黑树上,通过回调函数内核会将 I/O 准备好的描述符加入到一个链表中管理,进程调用 epoll_wait() 便可以得到事
件完成的描述符。
从上面的描述可以看出,epoll 只需要将描述符从进程缓冲区向内核缓冲区拷贝一次,并且进程不需要通过轮询来获
得事件完成的描述符。
epoll 仅适用于 Linux OS。
epoll 比 select 和 poll 更加灵活而且没有描述符数量限制。

epoll 对多线程编程更有友好,一个线程调用了 epoll_wait() 另一个线程关闭了同一个描述符也不会产生像 select 和
poll 的不确定情况:

假设从epoll_wait收到100个事件,A事件造成B事件关闭,如果移除B事件结构并关闭文件描述符,事件缓存仍然认为有事件在等待文件描述符,从而造成混乱。

解决方法是,在A事件处理过程中,调用epoll_ctl(EPOLL_CTL_DEL)来移除B文件描述符关闭,然后标记关联的数据结构为已移除,并关联到移除列表。在后续事件处理过程中,当发现B文件描述符的新事件时,可以通过检查标记发现文件描述符已移除,避免产生混乱。

工作模式
epoll 的描述符事件有两种触发模式:LT(level trigger)和 ET(edge trigger)。
1. LT 模式
当 epoll_wait() 检测到描述符事件到达时,将此事件通知进程,进程可以不立即处理该事件下次调用 epoll_wait()
会再次通知进程。是默认的一种模式,并且同时支持 Blocking 和 No-Blocking
2. ET 模式
和 LT 模式不同的是,通知之后进程必须立即处理事件下次再调用 epoll_wait() 时不会再得到事件到达的通知。
很大程度上减少了 epoll 事件被重复触发的次数,因此效率要比 LT模式高只支持 No-Blocking,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。

应用场景
很容易产生一种错觉认为只要用 epoll 就可以了,select 和 poll 都已经过时了,其实它们都有各自的使用场景。
1. select 应用场景
select 的 timeout 参数精度为 1ns,而 poll 和 epoll 为 1ms,因此 select 更加适用于实时性要求比较高的场景,比
如核反应堆的控制。
select 可移植性更好,几乎被所有主流平台所支持。
2. poll 应用场景
poll 没有最大描述符数量的限制,如果平台支持并且对实时性要求不高,应该使用 poll 而不是 select。
3. epoll 应用场景
只需要运行在 Linux 平台上,有大量的描述符需要同时轮询并且这些连接最好是长连接。
需要同时监控小于 1000 个描述符,就没有必要使用 epoll,因为这个应用场景下并不能体现 epoll 的优势。
需要监控的描述符状态变化多,而且都是非常短暂的,也没有必要使用 epoll因为 epoll 中的所有描述符都存储在
内核中,造成每次需要对描述符的状态改变都需要通过 epoll_ctl() 进行系统调用,频繁系统调用降低效率。并且
epoll 的描述符存储在内核,不容易调试。

HTTP和HTTPS的区别,以及HTTPS有什么缺点?

原文地址:https://www.cnblogs.com/lxy-xf/p/11347528.html