HTttp历史

三问:

  1. 一问:客户端如何知道所求内容的地址? 对应技术:统一资源定位符url;
  2. 二问:当客户端知道所请求位置后,如何获取所求内容?对应技术:超文本传输协议http;
  3. 三问:请求到内容以何种形式展示以便客户端识别?对应技术:超文本标记语言html;

Http历史:

  1. Http0.9:
    1. 请求体:GET  XXX.XXXXX
    2. 传输内容类型:仅纯文本;
    3. 没有任何  404         500报错;
    4. 连接:一次请求,一次连接,用完关闭;
  1. Http1.0:
    1. 增加POST,发送表单信息;
    2. 增加HTTP头,可以返回错误代码;
    3. 增加传输类型:图片,动画;
    4. 允许保持连接:一次连接,多次通信;每一个请求都要建立一个连接
  2. Http1.1:
    1. 增加host头,请求的域名、Ip和端口号;
    2. 引入range头,制定下载那一部分;
    3. 允许保持连接:一次连接,多次通信,但是需要排队,一旦请求超时会造成堵塞;
  3. Http2.0:
    1. 二进制分帧;消息分割更小的消息和帧,减少慢启动时间和网络堵塞。
    2. 消息头压缩;SPDY算法升级压缩HPACK算法,爆头更加紧凑,更快传输,减少数据量网络堵塞。
    3. 流量控制;
    4. 多路复用;即资源共享.1.x 浏览器客户端在同一时间,针对同一域名下的请求有一定数量的限制,2.0可以并行交错的发送请求和响应,这些请求和响应之间互不影响,只使用一个链接即可并行发送多个请求和响应。(基于二进制分帧层)
    5. 请求优先;每个流都可以带有一个31bit的优先值:0表示最高优先级;2的31次方-1表示最低优先级。客户端明确指定优先级,服务端可以根据这个优先级作为交互数据的依据,比如客户端优先设置为.css>.js>.jpg。(基于二进制分帧层)
    6. 服务器推送;服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确的请求,而必须是经过双方的确认才行。
    7. 连接:多个请求同时连接一个连接上执行,且互不影响。
                   

HTTP的网络层次:

HTTP是基于传输层的TCP协议

  1. http开始前,建立连接:三次握手;
  2. 进行传输,持续连接???

 

HTTP是基于TCP协议的,所以每次都是客户端发送请求,服务器应答,但是TCP还可以给其他应用层提供服务,即可能A、B在建立链接之后,谁都可能先开始通信。

过程:

在发送完这些请求和头部之后,浏览器发送一个换行符,表示要发送的内容已经结束了。

服务器端返回一个响应码,指示这次请求的状态,响应的形式是这样的:

200 OK  浏览器没有跟服务器确认,直接用浏览器缓存。没网的时候???

[响应头部]

然后是一个换行,接下来有效载荷(payload),也就是 www.google.com 的HTML内容。服务器下面可能会关闭连接,如果客户端请求保持连接的话,服务器端会保持连接打开,以供之后的请求重用。

如果浏览器发送的HTTP头部包含了足够多的信息(例如包含了 Etag 头部),以至于服务器可以判断出,浏览器缓存的文件版本自从上次获取之后没有再更改过,服务器可能会返回这样的响应:

304 Not Modified(缓存)  浏览器和服务器多确认一次缓存有效性,在用缓存。

[响应头部]

这个响应没有有效载荷,浏览器会从自己的缓存中取出想要的内容。

发送请求:缓存是否过期?请求服务器       :        使用缓存

|                                   |

文件是否被修改?返回新文件:使用缓存(虽然过期但没被改动304使用缓存)。

在解析完 HTML 之后,浏览器和客户端会重复上面的过程,直到HTML页面引入的所有资源(图片,CSS,favicon.ico等等)全部都获取完毕,区别只是头部的 GET / HTTP/1.1 会变成 GET /$(相对www.google.com的URL) HTTP/1.1 。

如果HTML引入了 www.google.com 域名之外的资源,浏览器会回到上面解析域名那一步,按照下面的步骤往下一步一步执行,请求中的 Host 头部会变成另外的域名。

状态码

信息类 (100-199)

响应成功 (200-299)

重定向类 (300-399)

301和302表示重定向

浏览器在拿到服务器返回的状态码后自动跳转到一个新的Url地址,这个地址可以从响应的location首部中获取(用户看到的效果就是输入的地址瞬间变成了另一个地址B)。

 

301:表示旧地址被永久的移除;

302:表示旧地址还在,只是临时跳转到新地址;

304:缓存过期,发送请求,服务端返回304表示 本地文件虽然过期,但是服务器文件没被修改,可以继续使用本地文件。

客户端错误类 (400-499)

403:无权限;

404:找不到

服务端错误类 (500-599)

500:参数或者接口有问题;

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?

四次挥手,是因为建立连接时调用SYN发起一个新连接,服务器只是accept一下,就一次性发送了SYN和ACK标志位;而断开时客户端和服务端都要调一下close函数,所以两次close分别出发了两次FIN包,导致FIN和ACK合并为一个包,所以建立连接需要3次,关闭连接需要4次。

注意:关闭连接时当收到双发FIN报文时,仅仅表示不再发送数据了,还可以接受数据;可能数据未必都发送给对方,需要发送以数据后在关闭。所以需要FIN和ACK分开发送;

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

【问题3】为什么不能用两次握手进行连接?

全开工、半开工、单工

【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

为什么  ”三“次?
确定双方都能“发送”和“接收”。

两次不确定是否能收,四次造成浪费。

能发送就不能确定一定能接受吗?

不能。因为:根据双方的分工和传输方向 分为3种方式:

全双工:AB双方和同时发送消息,TCP是全双工的;

半全工:AB都可以发送消息,但是A可以给B发送消息的时候,B不能给A发;同理 B.

单攻:AB只能一方发送消息。

原文地址:https://www.cnblogs.com/yancongyang/p/11170205.html