目录
二、TCP三次握手和四次挥手的流程,断开连接如果只有两次握手,会出现什么。
三、TIME_WAIT 和 CLOSE_WAIT的区别
四、为什么需要 TIME_WAIT 状态
五、为什么 TIME_WAIT 状态要保持 2MSL 这么长时间
六、说说你知道的几种 HTTP 响应码
七、当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤
八、TCP/IP 如何保证可靠性,说说 TCP 头的结构
九、如何理解HTTP协议的无状态性
十、简述 Http 请求 get 和 post 的区别以及数据包格式
十一、HTTP 有哪些 method
十二、简述 HTTP 请求的报文格式
十三、HTTP 的长连接是什么意思
十四、HTTPS 的加密方式是什么,讲讲整个加密解密流程
十五、Http 和 Https 的三次握手有什么区别
十六、什么是分块传送
十七、http/1.0、http/1.1和http2.0有什么区别
十八、DNS使用的协议(既使用 TCP 也使用 UDP)
十九、TCP 粘包和拆包产生的原因
二十、WEB开发中 Forward 和 Redirected的区别
【1】Cookie 保存在客户端,未设置存储时间的 Cookie,关闭浏览器会话 Cookie 就会被删除;设置了存储时间的 Cookie 保存在用户设备的磁盘中直到过期,同时 Cookie 在客户端所以可以伪造,不是十分安全,敏感数据不易保存。Session 保存在服务器端,存储在 IIS 的进程开辟的内存中,而 Session 过多会消耗服务器资源,所以尽量少使用 Session。
【2】Session 是服务器用来跟踪用户的一种手段,每个 Session都有一个唯一标识:session ID。当服务端生成一个 Session 时就会向客户端发送一个 Cookie 保存到客户端,这个 Cookie 保存的是 Session 的 SessionID 这样才能保证客户端发起请求后,用户能够与服务器端成千上万的 Session 进行匹配,同时也保证了不同页面之间传值的正确性。
【3】存储数据类型不同:Session 能够存储任意的 Java 对象,Cookie 只能存储 String 类型的对象。
【4】大于10K 的数据,不要用到 Cookies。
【1】TCP三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。
第一次握手:建立连接时,客户端发送 syn(Synchronize Sequence Numbers:同步序列编号)包(seq=j)到服务器,并进入SYN_SEND(请求连接)状态,等待服务器确认。
第二次握手:服务器接收到 syn包,必须确认客户的 SYN(ack=j+1)(ack:确认字符,表示发来的数据已确认接收无误),同时自己也发送一个 syn包(seq=k),既 SYN+ACK 包,此时服务器进入SYN_RECV(发送了ACK)状态。
第三次握手:客户端收到服务端发送的 SYN+ACK 包,向服务端发送确认包 ACK(ack=k+1),包发送完毕,客户端与服务器进入 ESTABLISHED(TCP连接成功)状态,完成三次握手。
图1: TCP三次握手图
【2】TCP四次挥手(连接终止协议,性质为终止协议):
第一次挥手:TCP客户端发送一个FIN+ACK+SEQ,用来传输关闭客户端到服务端的数据。进入FIN_WAIT1状态。
第二次挥手:服务端收到FIN,被动发送一个ACK(SEQ+1),进入CLOSE_WAIT状态,客户端收到服务端发送的ACK,进入FIN_WAIT2状态。
第三次挥手:服务器关闭客户端连接,发送一个 FIN+ACK+SEQ 给客户端。进入 LAST_ACK 状态。
第四次挥手:客户端发送 ACK(ACK=SQE序号+1)报文确认,客户端进入 TIME_WAIT 状态,服务端收到 ACK 进入 CLOSE状态。
图2: TCP四次挥手
【3】由于TCP连接是双向的,因此每个方向都需要单独进行关闭。原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一个方向上没有数据流动,一个 TCP连接到一个 FIN后仍能发送数据。首次执行FIN的一方主动关闭,另一方则执行被动关闭。当只握手两次时,就只会关闭主动发起的一端,另一个仍能发送数据。
CLOSE_WAIT:等待关闭,是被动关闭连接形成的,也就是第二次挥手时产生的状态。也就是当对方 Close 一个 SOCKET 后发送 FIN 报文给自己,系统会回应一个 ACK 报文给对方,此时进入CLOSE_WAIT状态。接着,我们需要考虑的事情是查看是否还有数据发送给对方,如果没有就可以 Close 这个链接,发送 FIN 给对方,也既关闭连接。所以在 CLOSE_WAIT 状态时,需要查看自己是否需要关闭连接。
TIME_WAIT:是主动关闭连接方形成的,表示收到了对方的 FIN 报文,并发送 ACK 报文,等待 2MSL(Maximum Segment Lifetime:报文最大生存时间)约4分钟时间后进入 CLOSE 状态。主要是防止最后一个 ACK 丢失,由于 TIME_WAIT 等待时间较长,因此 server 端尽量减少关闭。
假设最终的 ACK 丢失,服务器将重新发送 FIN,客户端必须维护 TCP 状态信息以便可以重发最终的 ACK,否则发送 RST结果Server 认为发生错误。TCP 实现必须可靠的终止两端的连接(双工关闭),Client 必须进入TIME_WAIT 状态,因为最总的ACK可能发送失败。
如果 TIME_WAIT 状态保持时间不足2MSL,第一个连接可以正常关闭,但如果有相同的第二个连接出现,第一个连接的重复报文到达,就会干扰第二个连接。TCP 必须防止某个连接的重复报文在连接终止后出现,所以让 TIME_WAIT 状态等待时间大于2MSL,连接响应方向上的 TCP 报文要么完全响应完毕,要么被丢弃。建立二次连接时,就不会混淆。
【1】200 OK:表示客户端请求成功。
【2】400 Bad Request 语义有误:不能被当前服务器理解。
【3】401 Unauthorized: 当前请求需要用户验证。
【4】403 Forbidden: 服务器收到消息,但是拒绝提供服务。
【5】404 Not Found :请求资源不存在。
【6】408 Request Timeout: 请求超时,客户端没有在服务器预备等待的时间内完成发送。
【7】500 Internal Server Error: 服务器发生不可预期的错误。
【8】503 Server Unavailable :由于临时的服务器维护或过载,服务器当前不能处理请求,此状况知识临时的,可恢复。
1)、解析域名。
2)、发起 TCP 的 3 次握手。
3)、建立 TCP 请求后发起 HTTP 请求。
4)、服务器相应 HTTP 请求。
5)、浏览器得到 HTML 代码,进行解析和处理 JSON 数据,并请求 HTML 代码中的静态资源(JS、CSS、图片等)。
6)、浏览器对页面进行渲染。
1)、三次握手。
2)、将数据截断为合理的长度。应用数据被分割成 TCP 认为最合适发送的数据块。
3)、超时重发。
4)、对于收到的请求,给予确认响应。
5)、如果校验出数据包有错,则丢弃报文段,不响应。
6)、对失序数据进行重新排序,发送于客户端。
7)、能够丢弃重复数据。
8)、流量控制。TCP连接的两端都有缓存大小控制,接收端只允许发送端发送自己缓存剩余大小的数据。有效防止缓存溢出。
9)、拥塞控制。当网络阻塞时,减少数据的发送。
【TCP头结构】:
1)、源端口(source port)16 位的字段,定义了发送这个报文段的主机中的应用程序的端口号。
2)、目的端口(destination port)16 位的字段,定义了接收这个报文段的主机中的应用程序的端口号。
3)、序列号(sequence number)32 位的字段,定义了指派给本报文段第一个数据字节的编号。为了保证连接性,要发送的每一个字节都要编上号。序号可以告诉终点,报文段中的第一个字节是这个序列中的哪一个字节。在建立连接时,双方使用各自的随机数生成器生产一个初始序号(inital squence number,ISN),通常两个方向上的 ISN 是不同的。
4)、确认号(acknowledgment nimber)32 位字段定义了报文段的接收方期望从对方接收的字节编码。如果报文段的接收方成功地接收了对方发来的编号为x的字节,那么它就返回x+1作为确认号,确认可以和数据捎带在一起发送。
5)、头部长度(Hlen)(header length)这个4字节字段指出TCP段的头部长度,以32位字段来衡量,头部长度并不规定并可以根据选项字段中设置的参数面改变。
6)、保留(reserved)这个保留字段占用6位,它被保留以提供将来使用。
7)、URG 紧急数据(urgent data)---这是一条紧急信息。
8)、ACK 确认已收到段
9)、PSH 请求在缓冲区尚未填满时发送消息,注意TCP可以等待缓冲区填满之后再发送段,如果需要立即传送,应用程序必须利用push参数来通知协议。
10)、RST 申请重置连接。
11)、SYN 此消息用于在建立连接时同步传输数据的计时器。
12)、FIN 该属性申明发送端已经发送出被传输数据的最后一个字节。
13)、窗口大小(window)16位字段,这个字段定义的是发送TCP的窗口大小,以字节为单位。窗口最大长度是65535字节,这个值通常被称为接收窗口(rwnd),并由接收方来决定。这种情况下,发送方必须服从接收方的指示。
14)、校验和(checksum)16位字段包含的是检验和,检验和是差错控制的手段之一。
15)、紧急指针(urgent point)该字段占用2字节,与URG代码位一起使用并且申明及时使存在着缓冲区溢出也必须紧急接收的数据末端。因此,如果有些数据需要不按照顺序被送往目的应用程序,那么发送端的应用程序必须利用紧急数据参数通知TCP。
16)、选项(option)该字段为变长且可以忽略。他的最大长度为3字节,用于解决一些辅助任务----比如,选择最大段长。选项可以位于TCP头部的末端,其长度必须是8的倍数。
17)、填充(padding)该字段长度不固定,这是个用于补充头部字段使得它的长度为32位字的整数倍的一个伪字段9
HTTP协议是无状态的,指的是HTTP协议对于事务处理没有记忆功能,服务器不知道客户端是什么状态。相当于,打开一个服务器上的网页与上一次打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不代表HTTP使用的是UDP协议(无连接)。
【1】GET请求可被缓存,POST请求不能被缓存。
【2】GET请求被保留着浏览器历史记录中,POST请求不会被保留。
【3】GET请求能被收藏至书签中,POST请求不能被收藏至书签。
【4】GET请求不应在处理敏感数据时使用,POST可以用户处理敏感数据。
【5】 GET请求有长度限制,POST请求没有长度限制。
【6】POST不限制提交的数据类型,所以POST可以提交文件到服务器。
数据包格式 == TCP头结构
★ GET:获取资源。
★ POST:表单提交。
★ HEAD:获取报头信息,HEAD 方法与 GET 方法类似,但并不会返回响应主体。
★ PUT 与 PATCH:更新资源,PUT 对后台来说 PUT 方法的参数是一个完整的资源对象,它包含了对象的所有字段,PATCH 对后台来说 PATCH 方法的参数只包含我们需要修改的资源对象的字段。
★ DELETE:删除资源。
★ OPTIONS:获取目标资源所支持的通信选项,使用 OPTIONS 方法对服务器发起请求,以检测服务器支持哪些 HTTP 方法。
客户端与服务端通信时传输的内容我们称之为报文。
客户端发送给服务器的称为”请求报文“,服务器发送给客户端的称为”响应报文“。
图3 POST请求 报文格式
图4 GET请求 报文格式
图5 报文响应格式
长连接是指客户端与服务端建立连接后,不会因完成了一次请求后,它们之间的连接主动关闭。后续的读写操作会继续使用这个链接。 如果一个连接两小时内都没有任何动作,服务器会向客户端发送一个探测报文段、根据客户端主机相应探测4个客户端状态,①、客户端正常时,且服务器可达。此时客户端TCP响应正常,服务器将定时器复位。②、客户端已经崩溃,并且关闭或正在重启,客户端不能响应TCP,服务器将无法收到客户端对探测器的响应。服务器总共发送10个这样的探测,每间隔75秒。如服务器没有收到任何响应,他就认为客户端已经关闭并终止连接。③、客户端崩溃,但已重启。服务器将对其保持探测响应,这个响应是一个复位,使得服务器终止这个连接。④、 客户机正常运行,但是服务器不可达。这种与②类似。
由上可以看出,长连接可以省去较多的TCP建立和关闭操作,减少浪费,节约时间。对于频繁请求资源的客户端适合使用长连接。在长连接的应用场景下,client 端一般不会主动关闭连接,当 client 与 server 之间的连接一直不关闭,随着客户端连接越来越多,server 会保持过多连接。这时候 server 端需要采取一些策略,如关闭一些长时间没有请求发生的连接,这样可以避免一些恶意连接导致 server 端服务受损;如果条件允许则可以限制每个客户端的最大长连接数,这样可以完全避免恶意的客户端拖垮整体后端服务,例如:数据库的连接用长连接。
加密方式: 【1】对称密码算法:指加密和解密使用相同的密钥,速度高,可加密内容较大,用来加密会话过程中的消息。典型算法 DES、AES、RC5、IDEA(分组加密)RC4。
【2】非对称密码算法:又称为公钥加密算法,是指加密和解密使用不同的密钥,加密速度较慢,但能提供更好的身份认证技术,用来加密对称加密的密钥(公开的密钥用于加密,私有的密钥用于解密)典型的算法RSA、DSA、DH。
【3】散列算法:将文件内容通过此算法加密变成固定长度的值(散列值),这个过程可以使用密钥也可以不使用。这种散列变化是不可逆的,也就是说不能从散列值编程原文,因此散列变化通道常用语验证原文是否被篡改。典型的算法MD5、SHA、BASE64、CRC等。
注意:SSL协议在建立链路时,SSL首先对对称加密的密钥进行对公加密,链路建立好之后,SSL对传输内容使用对称加密。SSL加密过程:参考15问题图7 双向认证: 单向认证作为了解加密过程简化流程。
图6 单向认证
第三步:客户端使用服务端返回的信息验证服务器的合法性,包括:
1)、证书是否过期。
2)、发布服务器证书的CA是否可靠。
3)、返回的公钥是否能正确解开返回证书中的数字签名。
4)、服务器证书上的域名是否和服务器实际域名相匹配。
题目2中所说的握手为 HTTP 握手的流程,Https 在 Http 的基础上加入了 SSL/TSL 协议,SSL 依靠证书来验证服务器的身份,并为服务器与浏览器之间的通信加密。下图为HTTPS的握手流程。
图7 双向认证
1)、分块传送是超文本协议HTTP中的一种传输机制,允许HTTP由网页服务器发送给客户端应用(通常是网页浏览器)的数据可以分成多个部分。分块传送只在HTTP/1.1中提供。HTTP应答消息中发送的数据是整个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。通常数据块的大小是一致的,但也不总是这种情况。
2)、对于在发送HTTP头部前,无法计算出 Content-Length 的 HTTP 请求及回复(例如 WEB 服务端产生的动态内容),可以使用分块传输,使得不至于等待所有数据产生后,再发送带有 Content-Length 的 HTTP 头部,而是将已经产生的数据一块一块发送出去。
3)、HTTP BODY 数据成连续的块传输,每块数据的最开始处,指明了该数据块的大小,随后则是CRLF,数据,及结尾CRLF。可见每块数据都是包含在两个CRLF之间,最后一块数据则是0CRLFCRLF,两个CRLF之间没有任何数据;数据大小以16进制字符串表示(不是二进制)。
4)、客户端发送请求时,也可以使用分块传输,但是一般客户端发送请求前,不知道服务端是否支持分块传输,所以,客户端可以发送HTTP头部,表明使用分块传输,假如服务端不支持,将会回复 411(Length Required) 错误,中断请求。
【1】http/1.0 协议默认使用非持久连接,既在非持久连接下,服务器处理完客户端请求后立即断开 TCP 连接,服务器不跟踪每个客户,也不记录过去的请求。
【2】http/1.1 协议默认使用持久连接,既一个 TCP 可以传输多个 WEB 对象。同时也可通过配置支持非持久连接。
【3】http/1.1 增加了 Host 字段,因为目前一台计算机上有多个虚拟主机共享一个IP地址,请求和响应消息都应该支持 Host 头信息,且请求消息中没有 Host 头信息会报(400 Bad Request)。此外服务器应该接受以绝对路径标记的资源请求。而 http/1.0 中每台服务器都绑定一个唯一的IP,因此,请求消息中的 URL 没有传递主机名(HostName)。
【4】增加了新的状态码 100(Continue)。客户端事先发送一个只带头域的请求,如果服务因权限等拒绝请求,就回送401(Unauthorized)或403;如果服务器接受此请求就回送100,客户端就可以继续发送带实体的完成请求。状态码的使用,在request 发送 body 之前,先发送 header 试探一下 server,如果接受 body,再发送 body。可以节省带宽。
【5】http/1.0 加入了分块编码(Chunked TransferCoding)。发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后一个零长度的块作为消息的结束标志。这种发送允许发送方只缓存一个片段,避免缓存整个片段带来的过载。
【6】http/1.1 在 http/1.0 的基础上加入了一些 Cache 的新特性,当缓存对象 Ag e超过 Expire 时变为 stale 对象,Cache 不需要直接抛弃 stale 对象,而是与源服务器进行重新激活(revalidation)
【7】http/2.0 支持多路复用技术,同一个连接并发处理多个请求(NIO),http/1.1 可以通过建立多个 TCP 解决。
【8】http/1.1 不支持 Header 数据的压缩,http/2.0 使用 HPACK算法对数据压缩,降体积提速度。
【9】http/2.0 请求服务器,服务器推送数据时会额外推送客户需要的资源,客户下次调用不用请求直接调用。提升速度。
【1】首先了解一下 TCP与 UDP传送字节的长度限制:UDP报文的最大长度为 512字节,而 TCP则允许报文长度超过 512字节。当 DNS查询超过 512字节时,协议的 TC标志出现删除标志,这时则使用 TCP发送。通常传统的 UDP报文一般不会大于512字节。
【2】区域传送时使用TCP,主要有一下两点考虑:辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用 TCP而不是 UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。TCP是一种可靠的连接,保证了数据的准确性。
【3】域名解析时使用 UDP 协议:客户端向 DNS 服务器查询域名,一般返回的内容都不超过 512 字节,用 UDP 传输即可。不用经过 TCP 三次握手,这样 DNS 服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向 DNS 服务器查询的时候使用 TCP,但事实上,很多 DNS 服务器进行配置的时候,仅支持 UDP 查询包。
【1】应用程序写入数据的字节大小大于套接字发送缓冲区的大小。
【2】进行 MSS 大小的 TCP 分段。MSS是最大报文段长度的缩写。MSS 是 TCP 报文段中的数据字段的最大长度。数据字段加上 TCP 首部才等于整个的 TCP 报文段。所以 MSS 并不是 TCP 报文段的最大长度,而是MSS=TCP报文段长度-TCP首部长度
【3】以太网的 payload 大于 MTU 进行 IP 分片。MTU指:一种通信协议的某一层上面所能通过的最大数据包大小。如果 IP 层有一个数据包要传,而且数据的长度比链路层的 MTU 大,那么 IP 层就会进行分片,把数据包分成若干片,让每一片都不超过MTU。注意,IP 分片可以发生在原始发送端主机上,也可以发生在中间路由器上。
【解决办法】:【1】消息定长。例如100字节。
【2】在包尾部增加回车或者空格符等特殊字符进行分割,典型的如FTP协议
【3】将消息分为消息头和消息尾。
【4】其它复杂的协议,如 RTMP协议等。
【1】间接请求转发(Redirect):实际是两次 HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个 URL发出请求,从而达到转发的目的。一般用于避免用户的非正常访问。例如:用户在没有登录的情况下访问后台资源,Servlet可以将该HTTP请求重定向到登录页面,让用户登录以后再访问。在Servlet中,通过调用 response对象的 SendRedirect()方法,告诉浏览器重定向访问指定的URL,示例代码如下:
//Servlet中处理get请求的方法
public void doGet(HttpServletRequest request,HttpServletResponse response){
//请求重定向到另外的资源
response.sendRedirect("资源的URL");
}
【2】直接请求转发(Forward):客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象 request中,保存的对象对于每个信息资源是共享的。
----架构师成长路线,关注公众号获取----