1、http1.0、http1.1和http2.0有什么区别。
(一)、Http1.0和Http1.1的区别
长连接: Http1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务端要建立一个长连接。
节约带宽: HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象传送过来,并且不支持断点续传功能。HTTP1.1支持只发送header信息(不包括body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求的body发送到服务器;如果返回401,客户端就可以不用发送请求body了,节约带宽。
HOST域: 在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名,HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误。
**缓存处理:**在HTTP1.0中主要使用header里的If-Modified-Since,Expires来作为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略,例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
错误通知的管理: 在HTTP1.1中新增了24个错误状态码,如409(Conflict)表示请求的资源与资源的当前状态冲突;410(Gone)表示服务器上的某个资源被永久性地删除了。
(二)、HTTP1.1和HTTP 2.0的区别
多路复用: HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。
头部数据压缩: 在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也会越来越多,导致消耗在头部的流量越来越多,尤其每次都要传输UserAgent,Cookie这类不会频繁变动的内容,完全是一种浪费。HTTP1.1中不支持header部分数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会很快。
服务器推送: 服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP1.1中这些资源每一个都必须明确地请求,这是一个很慢的过程。浏览器从获取HTML开始,然后解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常处于空闲和未充分使用的状态。
为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。
2、TCP三次握手和四次挥手的流程,为什么断开连接要4次,如果握手只有两次,会出现什么。
(一)三次握手
三次握手其实就是指建立一个TCP连接,需要客户端和服务端总共发送3个包。进行3次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双发的序列号和确认号,交换TCP窗口大小信息。
刚开始时客户端处于Closed状态,服务端处于Listen状态。
进行3次握手:
1、第一次握手: 客户端给服务端发送一个SYN报文,并指明客户端的初始序列号为X,此时客户端处于SYN_SENT状态。
2、第二次握手: 服务端接收到客户端的SYN报文后,会以自己的SYN报文作为应答,并且指定自己的序列号为y,同时把客户端的序列号加1作为确认号ask,表示服务端已经接收到客户端的SYN报文,此时服务器处于SYN_RCVD的状态。
3、第三次握手: 客户端收到服务端返回的SYN报文后,会发送一个ACK报文,将服务端的序列号+1作为ask信息,并且将序列号+1作为新的序列号,表示已经收到了服务端的SYN报文,此时客户端处于ESTABLISHED状态。服务端接收到ACK报文后妈耶处于ESTABLISHED状态。
为什么需要三次握手。两次不行吗?
弄清这个问题,我们需要先弄明白三次握手分别的含义以及目的,能不能通过两次握手来实现相同的目的。
- 第一次握手:客户端发送网络包,服务端接收到了。这样服务端就可以得出结论:客户端的发送能力和服务端的接收能力是正常的。
- 第二次握手:服务端发送网络包,客户端接收到了,这样客户端就能得出结论:服务端的接收能力、发送能力,客户端的接收能力、发送能力是正常的。但是这是服务端并没法知道客户端的接收能力是否正常。
- 第三次握手:客户端发包,服务端收到了,这样服务端才能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
因此,需要三次握手才能确认双方的接收和发送能力是否正常。
试想如果是用两次握手,则会出现下面这种情况:
如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。
什么是半连接队列?
服务器第一次收到客户端的 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 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
SYN攻击是什么?
服务器端的资源分配是在二次握手时分配的,而客户端的资源分配是在完成三次握手时分配的,所以服务器端容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。netstat -n -p TCP | grep SYN_RECV
(二)四次挥手
建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。
刚开始双方都处于ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:
1、第一次挥手: 客户端发送一个FIN报文,报文中会指定一个序列号u,此时客户端处于FIN_WAIT1状态。即发出连接释放报文(FIN=1,seq = u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
2、第二次挥手: 服务端接收到FIN报文后,会发送ACK报文,且将客户端的序列号+1作为ack的值,以及自己的序列号v发送给客户端,表示自己已经接收到客户端的报文了,此时服务端处于CLOSE_WAIT状态。此时TCP处于半关闭状态,客户端到服务端的连接释放。客户端在收到服务端的确认后,进入FIN_WAIT2状态,等待服务端发出的连接释放报文段。
3、第三次挥手: 如果服务端也想断开连接,和客户端的第一挥手一样,发送FIN报文,且指定一个序列号,此时服务端处于LAST_ACK状态。即服务端没有要向客户端发出的数据,服务端发出连接释放报文段。
4、第四次挥手: 客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
挥手为什么需要4次?
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
2MSL等待状态
TIME_WAIT状态也称为2MSL等待状态。每一个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment LifeTime),它是任何报文被丢弃前在网络中的最长时间。这个时间是有限的,因此TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。
四次挥手释放连接,等待2MSL的意义?
为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
两个理由:
1、保证客户端发送的最后一个ACK报文段能够到达服务端。
这个ACK报文段有可能丢失,使得处于LAST_ACK状态的服务端收不到对已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,最后客户端和服务端都进入到CLOSED状态,若客户端在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到服务端重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。
2、防止“已失效的连接请求报文段”出现在本连接中
客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
3、TIME_WAIT和CLOSE_WAIT的区别。
CLOSE_WAIT: CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。
TIME_WAIT: 客户端接收到服务端的FIN报文以及对服务端发送ACK报文后,所处的状态,需要等待2MSL时间才能转换成CLOSED状态。
4、说说你知道的几种HTTP响应码,比如200, 302, 404。
Http响应码:
- 200 OK //客户端请求成功
- 301 Moved Permanently //永久重定向,使用域名跳转
- 302 Found // 临时重定向,未登陆的用户访问用户中心重定向到登录页面
- 400 Bad Request //客户端请求有语法错误,不能被服务器所理解
- 401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
- 403 Forbidden //服务器收到请求,但是拒绝提供服务
- 404 Not Found //请求资源不存在,eg:输入了错误的URL
- 409(Conflict)表示请求的资源与资源的当前状态冲突;
- 410(Gone)表示服务器上的某个资源被永久性地删除了。
- 500 Internal Server Error //服务器发生不可预期的错误
- 503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
5、当你用浏览器打开一个链接(如:http://www.baidu.cn)的时候,计算机做了哪些工作步骤。
1、根据域名和DNS解析得到服务器的IP地址(DNS+CDN)。
2、通过ARP协议获得IP地址对应的物理机器的MAC地址。
3、浏览器对服务器发起TCP3次握手。
4、建立TCP连接后发起HTTP请求报文。
5、服务器响应HTTP请求,将响应报文返回给浏览器。
6、短连接情况下,请求结束则通过TCP4次挥手关闭连接,长连接在没有访问服务器的若干时间后,进行连接的关闭。
7、浏览器得到响应的HTML代码,并请求HTML代码中的资源(如js,css,图片等)。
8、浏览器对页面进行渲染并呈现给用户。
域名解析过程:
1、浏览器首先检查自己本地是否缓存对应的域名,有则直接使用。
2、如果浏览器的缓存中并没有域名,则查询系统DNS缓存中的域名表,有则直接使用。
3、如果没有,则检查本地hosts文件中是否存在域名与IP的映射,有则直接使用。
4、本地如果都找不到,则向域名服务器发起请求查询。
5、域名服务器发起迭代请求,首先向根域名服务器发起请求,假如本次请求的是www.baidu.com,根域名服务器发现这个是com的顶级域名,就把com域的ip地址返回给DNS服务器。(根域名服务器)
6、DNS服务器向com域IP地址发起请求,查询该域名的ip,此时该服务器返回了baidu.com的DNS地址。(顶级域名服务器)
7、最后DNS服务器又向baidu.com的DNS地址发起查询请求,最后找到完整的ip地址返回给DNS服务器,DNS服务器再把IP信息返回给windows内核,内核再返回给浏览器,于是浏览器就知道该域名对应的ip地址了,可以进一步请求了。(权限域名服务器)
DNS请求原理
每个域名用小数点分隔开变成多级,从右到左等级逐级递减,所以最右边的等级最高,每个域都有用一个域名服务器,管理则下属域名,分布如下图:
所以DNS发送查询请求的时候,先从根服务器获对应顶级域名的ip,然后再逐级从定义域名ip向下查找各个下属域服务的,找到完整的域名ip。这是一个迭代查询的过程。
6、TCP/IP如何保证可靠性,说说TCP头的结构。
TCP协议保证数据传输可靠性的方式主要有:
- 校验和
- 序列号
- 确认应答
- 超时重传
- 连接管理
- 流量控制
- 拥塞控制
校验和
计算方式: 在数据传输的过程中,将发送的数据段都当做一个16位的整数。将这些整数加起来。并且前面的进位不能丢弃,补在后面,最后取反,得到校验和。
发送方: 在发送数据之前计算检验和,并进行校验和的填充。
接收方: 收到数据后,对数据以同样的方式进行计算,求出校验和,与发送方的进行比对。
注意:如果接收方比对校验和与发送方不一致,那么数据一定传输有误。但是如果接收方比对校验和与发送方一致,数据不一定传输成功。
确认应答与序列号
序列号: TCP传输时将每个字节的数据都进行了编号,这就是序列号。
确认应答: TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。
序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。这也是TCP传输可靠性的保证之一。
超时重传
在进行TCP传输时,由于确认应答与序列号机制,也就是说发送方发送一部分数据后,都会等待接收方发送的ACK报文,并解析ACK报文,判断数据是否传输成功。如果发送方发送完数据后,迟迟没有等到接收方的ACK报文,这该怎么办呢?而没有收到ACK报文的原因可能是什么呢?
首先,发送方没有接收到响应的ACK报文原因可能有两点:
1、数据在传输过程中由于网络原因导致直接全体退包,接收方根本接收不到。
2、接收方接收到了响应数据,但是发送的ACK报文响应却因为网络原因丢包了。
TCP在解决这个问题的时候引入了超时重传机制,简单理解就是发送方在发送完数据后等待一个时间,时间到达没有接收到ACK报文,那么对刚才发送的数据进行重新发送。如果是刚才第一个原因,接收方收到二次重发的数据后,便进行ACK应答。如果是第二个原因,接收方发现接收的数据已存在(判断存在的根据就是序列号,所以上面说序列号还有去除重复数据的作用),那么直接丢弃,仍旧发送ACK应答。
在Linux中(BSD Unix和Windows下也是这样)超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。重发一次后,仍未响应,那么等待2500ms的时间后,再次重传。等待4500ms的时间继续重传。以一个指数的形式增长。累计到一定的重传次数,TCP就认为网络或者对端出现异常,强制关闭连接。
连接管理
连接管理就是三次握手和四次挥手,保证可靠的连接,是保证可靠传输的前提。
流量控制
接收端在接收到数据后,对其进行处理。如果发送端的发送速度太快,导致接收端的结束缓冲区很快的填充满了。此时如果发送端仍旧发送数据,那么接下来发送的数据都会丢包,继而导致丢包的一系列连锁反应,超时重传呀什么的。而TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制就是流量控制。
在TCP协议的报头信息当中,有一个16位字段的窗口大小。在介绍这个窗口大小时我们知道,窗口大小的内容实际上是接收端接收数据缓冲区的剩余大小。这个数字越大,证明接收端接收缓冲区的剩余空间越大,网络的吞吐量越大。接收端会在确认应答发送ACK报文时,将自己的即时窗口大小填入,并跟随ACK报文一起发送过去。而发送方根据ACK报文里的窗口大小的值的改变进而改变自己的发送速度。如果接收到窗口大小的值为0,那么发送方将停止发送数据。并定期的向接收端发送窗口探测数据段,让接收端把窗口大小告诉发送端。
注:16位的窗口大小最大能表示65535个字节(64K),但是TCP的窗口大小最大并不是64K。在TCP首部中40个字节的选项中还包含了一个窗口扩大因子M,实际的窗口大小就是16位窗口字段的值左移M位。每移一位,扩大两倍。
拥塞控制
TCP传输的过程中,发送端开始发送数据的时候,如果刚开始就发送大量的数据,那么就可能造成一些问题。网络可能在开始的时候就很拥堵,如果给网络中在扔出大量数据,那么这个拥堵就会加剧。拥堵的加剧就会产生大量的丢包,就对大量的超时重传,严重影响传输。
所以TCP引入了慢启动的机制,在开始发送数据时,先发送少量的数据探路。探清当前的网络状态如何,再决定多大的速度进行传输。这时候就引入一个叫做拥塞窗口的概念。发送刚开始定义拥塞窗口为 1,每次收到ACK应答,拥塞窗口加 1。在发送数据之前,首先将拥塞窗口与接收端反馈的窗口大小比对,取较小的值作为实际发送的窗口。
拥塞窗口的增长是指数级别的。慢启动的机制只是说明在开始的时候发送的少,发送的慢,但是增长的速度是非常快的。为了控制拥塞窗口的增长,不能使拥塞窗口单纯的加倍,设置一个拥塞窗口的阈值,当拥塞窗口大小超过阈值时,不能再按照指数来增长,而是线性的增长。在慢启动开始的时候,慢启动的阈值等于窗口的最大值,一旦造成网络拥塞,发生超时重传时,慢启动的阈值会为原来的一半(这里的原来指的是发生网络拥塞时拥塞窗口的大小),同时拥塞窗口重置为 1。
拥塞控制是TCP在传输时尽可能快的将数据传输,并且避免拥塞造成的一系列问题。是可靠性的保证,同时也是维护了传输的高效性。
TCP的头部结构
基于TCP/IP的四层协议的信息封装如下所示:
TCP报文头部如下:
或者更详细点:
**16位端口号:**标示该段报文来自哪里(源端口)以及要传给哪个上层协议或应用程序(目的端口)。进行tcp通信时,一般client是通过系统自动选择的临时端口号,而服务器一般是使用知名服务端口号或者自己指定的端口号。
**32位序列号:**表示一次tcp通信过程(从建立连接到断开)过程中某一次传输方向上的字节流的每个字节的编号。假定主机A和B进行tcp通信,A传送给B一个tcp报文段中,序号值被系统初始化为某一个随机值ISN,那么在该传输方向上(从A到B),后续的所有tcp报文断中的序号值都会被设定为ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如某个TCP报文段传送的数据是字节流中的第1025~2048字节,那么该报文段的序号值就是ISN+1025。
**32位确认号:**用作对另一方发送的tcp报文段的响应。其值是收到对方的tcp报文段的序号值+1。假定主机A和B进行tcp通信,那么A发出的tcp报文段不但带有自己的序号,也包含了对B发送来的tcp报文段的确认号。反之也一样。
4位头部长度:表示tcp头部有多少个32bit字(4字节),因为4位最大值是15,所以最多有15个32bit,也就是60个字节是最大的tcp头部长度。
6位标志位:
URG:紧急指针是否有效
ACK:表示确认好是否有效,携带ack标志的报文段也称确认报文段
PSH:提示接收端应用程序应该立即从tcp接受缓冲区中读走数据,为后续接收的数据让出空间
RST:表示要求对方重建连接。带RST标志的tcp报文段也叫复位报文段
SYN:表示建立一个连接,携带SYN的tcp报文段为同步报文段
FIN标志:表示告知对方本端要关闭连接了。
16位窗口大小:是TCP流量控制的一个手段,这里说的窗口是指接收通告窗口,它告诉对方本端的tcp接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
16位校验和: 由发送端填充,接收端对tcp报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意这个校验不仅包括tcp头部,也包括数据部分。这也是tcp可靠传输的一个重要保障。
16位紧急指针: 是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此这个字段是紧急指针相对当前序号的偏移量。不妨称之为紧急便宜,发送紧急数据时会用到这个。
**TCP头部选项:**最后一个选项字段是可变长的可选信息,最多包含40字节的数据。典型的tcp头部选项结构:
kind表示选项的类型,length表示选项的长度(全部),info表示选项的具体内容,常见的头部选项有以下7种:
7、如何避免浏览器缓存。
https://blog.youkuaiyun.com/cbjcry/article/details/84719662
https://www.cnblogs.com/redirect/p/10066702.html#1-%E8%AF%B7%E6%B1%82%E6%8A%A5%E6%96%87
https://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247486310&idx=1&sn=3e5e02e7dd857d92e8cc2bc703133555&chksm=eb538e50dc24074613d5fedca4467a16cc0e0b35bfb90f9bc1717f8bb0c4d330c7ae961b36fa&scene=21#wechat_redirect
8、如何理解HTTP协议的无状态性。
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。
HTTP 是一个无状态协议,这意味着每个请求都是独立的,Keep-Alive 没能改变这个结果。
缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP 协议这种特性有优点也有缺点,优点在于解放了服务器,每一次请求“点到为止”不会造成不必要连接占用,缺点在于每次请求会传输大量重复的内容信息。
客户端与服务器进行动态交互的 Web 应用程序出现之后,HTTP 无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持 HTTP 连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。
Cookie 是客户端的存储空间,由浏览器来维持。具体来说 cookie 机制采用的是在客户端保持状态的方案。
Cookie 的实现过程:
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie,当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
也就是 Cookie 是服务器生成的,但是发送给客户端,并且由客户端来保存。每次请求加上 Cookie就行了。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
与 Cookie 相对的一个解决方案是 Session,它是通过服务器来保持状态的。
当客户端访问服务器时,服务器根据需求设置 Session,将会话信息保存在服务器上,同时将标示 Session 的 SessionId 传递给客户端浏览器,浏览器将这个 SessionId 保存在内存中,我们称之为无过期时间的 Cookie。浏览器关闭后,这个 Cookie 就会被清掉,它不会存在于用户的 Cookie 临时文件。
以后浏览器每次请求都会额外加上这个参数值,服务器会根据这个 SessionId,就能取得客户端的数据信息。
如果客户端浏览器意外关闭,服务器保存的 Session 数据不是立即释放,此时数据还会存在,只要我们知道那个 SessionId,就可以继续通过请求获得此 Session 的信息,因为此时后台的 Session 还存在,当然我们可以设置一个 Session 超时时间,一旦超过规定时间没有客户端请求时,服务器就会清除对应 SessionId 的 Session 信息。
9、简述Http请求get和post的区别以及数据包格式。
GET请求:
1、请求参数附在URL后
2、GET请求可被缓存
3、GET请求保留在浏览器的历史记录中。
4、GET请求不应在处理敏感数据的时候使用。
5、GET请求有长度限制
6、GET请求应当只用于获取数据。
POST请求:
1、请求参数附在请求体中。
2、POST不会被缓存
3、POST 请求不会保留在浏览器历史记录中
4、POST 请求对数据长度没有要求
HTTP请求数据包格式
Http请求数据包:请求行 + 请求头 + 数据体
(1)请求行
包含三个内容 method + request-URI + http-version。
method 包含有 post , get, head,delete, put, connect, options, patch, propfind, propatch, mkcol, copy, move, lock, unlock, trace, head。
request-URI :请求地址
http-version:http协议版本
(2)请求头
Accept:指浏览器或其他客户可以接爱的MIME文件格式。Servlet可以根据它判断并返回适当的文件格式。
User-Agent:是客户浏览器名称。
Host:对应网址URL中的Web名称和端口号。
Accept-Langeuage:指出浏览器可以接受的语言种类,如en或en-us,指英语。
connection:用来告诉服务器是否可以维持固定的HTTP连接。http是无连接的,HTTP/1.1使用Keep-Alive为默认值,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接
Cookie:浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
Referer:表明产生请求的网页URL。如比从网页/icconcept/index.jsp中点击一个链接到网页/icwork/search,在向服务器发送的GET/icwork/search中的请求中,Referer是http://hostname:8080/icconcept/index.jsp。这个属性可以用来跟踪Web请求是从什么网站来的。
User-Agent:是客户浏览器名称。
Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得。
Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859-1.
Accept-Encoding:指出浏览器可以接受的编码方式。编码方式不同于文件格式,它是为了压缩文件并加速文件传递速度。浏览器在接收到Web响应之后先解码,然后再检查文件格式。
(3)数据体
HTTP响应数据包
http响应数据包:状态行 + 响应头 + 响应正文
10、HTTP有哪些method
1、get:客户端向服务端发起请求,获得资源。请求获得URL处所在的资源。
2、post:向服务端提交新的请求字段。请求URL的资源后添加新的数据。
3、head:请求获取URL资源的响应报告,即获得URL资源的头部
4、patch:请求局部修改URL所在资源的数据项
5、put:请求修改URL所在资源的数据元素。
6、delete:请求删除url资源的数据
11、简述HTTP请求的报文格式。
HTTP请求数据包格式
Http请求数据包:请求行 + 请求头 + 数据体
(1)请求行
包含三个内容 method + request-URI + http-version。
method 包含有 post , get, head,delete, put, connect, options, patch, propfind, propatch, mkcol, copy, move, lock, unlock, trace, head。
request-URI :请求地址
http-version:http协议版本
(2)请求头
Accept:指浏览器或其他客户可以接爱的MIME文件格式。Servlet可以根据它判断并返回适当的文件格式。
User-Agent:是客户浏览器名称。
Host:对应网址URL中的Web名称和端口号。
Accept-Langeuage:指出浏览器可以接受的语言种类,如en或en-us,指英语。
connection:用来告诉服务器是否可以维持固定的HTTP连接。http是无连接的,HTTP/1.1使用Keep-Alive为默认值,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接
Cookie:浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
Referer:表明产生请求的网页URL。如比从网页/icconcept/index.jsp中点击一个链接到网页/icwork/search,在向服务器发送的GET/icwork/search中的请求中,Referer是http://hostname:8080/icconcept/index.jsp。这个属性可以用来跟踪Web请求是从什么网站来的。
User-Agent:是客户浏览器名称。
Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得。
Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859-1.
Accept-Encoding:指出浏览器可以接受的编码方式。编码方式不同于文件格式,它是为了压缩文件并加速文件传递速度。浏览器在接收到Web响应之后先解码,然后再检查文件格式。
(3)数据体
12、HTTP的长连接是什么意思。
在HTTP1.0和HTTP1.1协议中都有对长连接的支持。其中HTTP1.0需要在request中增加”Connection: keep-alive“ header才能够支持,而HTTP1.1默认支持.
http1.0请求与服务端的交互过程:
1、客户端发出带有包含一个header:”Connection: keep-alive“的请求
2、服务端接收到这个请求后,根据http1.0和”Connection: keep-alive“判断出这是一个长连接,就会在response的header中也增加”Connection: keep-alive“,同是不会关闭已建立的tcp连接.
3、客户端收到服务端的response后,发现其中包含”Connection: keep-alive“,就认为是一个长连接,不关闭这个连接。并用该连接再发送request.转到a),点击这里了解 http 1.0 vs 2.0 区别。
13、HTTPS的加密方式是什么,讲讲整个加密解密流程。
HTTP 协议中的内容都是明文传输,HTTPS 的目的是将这些内容加密,确保信息传输安全。最后一个字母 S 指的是 SSL/TLS 协议,它位于 HTTP 协议与 TCP/IP 协议中间。
14、Http和https的三次握手有什么区别。
15、什么是分块传送。
16、Session和cookie的区别。
什么是会话?
所谓的会话过程就是指从打开浏览器到关闭浏览器的过程。
1、Cookies是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术。Cookies是当你浏览某网站时,由Web服务器置于你硬盘上的一个非常小的文本文件,它可以记录你的用户ID、密码、浏览过的网页、停留的时间等信息。session: 当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。cookie机制:采用的是在客户端保持状态的方案,而session机制采用的是在服务端保持状态的方案。同时我们看到由于服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助cookie机制来达到保存标识的目的。
2、Session是服务器用来跟踪用户的一种手段,每个Session都有一个唯一标识:session ID。当服务器创建了Session时,给客户端发送的响应报文包含了Set-cookie字段,其中有一个名为sid的键值对,这个键值Session ID。客户端收到后就把Cookie保存浏览器,并且之后发送的请求报表都包含SessionID。HTTP就是通过Session和Cookie这两个发送一起合作来实现跟踪用户状态,Session用于服务端,Cookie用于客户端
本文借鉴以下文章:
HTTP1.0和HTTP1.1和HTTP2.0的区别
面试官,不要再问我三次握手和四次挥手
网络基础:TCP协议-如何保证传输可靠性
理解TCP报文段的头部结构