JAVA面试——TCP与HTTP

1、http/1.0、http/1.1和http2.0有什么区别。

      (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的新特性,当缓存对象Age超过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请求服务器,服务器推送数据时会额外推送客户需要的资源,客户下次调用不用请求直接调用。提升速度。

2、TCP三次握手和四次挥手的流程,为什么断开连接要4次,如果握手只有两次,会出现什么。

      (1)、TCP三次握手:
                 第一次握手:建立连接时,客户端发送syn(Synchronize Sequence Numbers:同步序列编号)包(sny=1)到服务器,并进入SYN_SEND(请求连接)状态,等待服务器确认;
                  第二次握手:服务器接收到syn包,必须确认客户的syn(ack=j+1)(ack:确认字符,表示发来的数据已确认接收无误),同时自己也发送一个syn包(sny=k),既ack+syn包,此时服务器进入SYN_RECV(发送了ACK时的状态)状态。
                  第三次握手:客户端收到服务端发送的syn+ack包,向服务端发送确认包ack(sny+1既ack=k+1),此包发送完毕,客户端与服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
                   JAVA面试——TCP与HTTP
                                                    图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状态。
                   JAVA面试——TCP与HTTP
                                                                          图2: TCP四次挥手
      (3)、由于TCP连接时双工的,因此每个方向都需要单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一个方向上没有数据流动,一个TCP连接到一个FIN后仍能发送数据。首次执行FIN的一方主动关闭,另一方则执行被动关闭。当只握手两次时,就只会关闭主动发起的一端,另一个仍能发送数据。

3、TIME_WAIT和CLOSE_WAIT的区别。

      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端尽量减少关闭。

4、为什么需要TIME_WAIT状态?

     假设最终的ACK丢失,服务器将重新发送FIN,客户端必须维护TCP状态信息以便可以重发最终的ACK,否则发送RST,结果Server认为发生错误。TCP实现必须可靠的终止两端的连接(双工关闭),Client必须进入TIME_WAIT状态,因为最总的ACK可能发送失败。

5、为什么TIME_WAIT状态要保持2MSL这么长时间?

     如果TIME_WAIT状态保持时间不足2MSL,第一个连接可以正常关闭,但如果有相同的第二个连接出现,第一个连接的重复报文到达,就会干扰第二个连接。TCP必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态等待时间大于2MSL,连接响应方向上的TCP报文要么完全响应完毕,要么被丢弃。建立二次连接时,就不会混淆。

6、说说你知道的几种HTTP响应码。

      ☆ 200 OK:表示客户端请求成功。
      ☆ 400 Bad Request 语义有误,不能被当前服务器理解。
      ☆ 401 Unauthorized 当前请求需要用户验证。
      ☆ 403 Forbidden 服务器收到消息,但是拒绝提供服务。
      ☆ 404 Not Found 请求资源不存在。
      ☆ 408 Request Timeout 请求超时,客户端没有在服务器预备等待的时间内完成发送。
      ☆ 500 Internal Server Error 服务器发生不可预期的错误。
      ☆ 503 Server Unavailable 由于临时的服务器维护或过载,服务器当前不能处理请求,此状况知识临时的,可恢复。

7、当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤。

     (1)、解析域名。
     (2)、发起TCP的3次握手。
     (3)、建立TCP请求后发起HTTP请求。
     (4)、服务器相应HTTP请求。
     (5)、浏览器得到HTML代码,进行解析和处理JSON数据,并请求HTML代码中的静态资源(JS、CSS、图片等)。
     (6)、浏览器对页面进行渲染。

8、TCP/IP如何保证可靠性,说说TCP头的结构。

      (1)、三次握手。
      (2)、将数据截断为合理的长度。应用数据被分割成TCP认为最合适发送的数据块。
      (3)、超时重发。
      (4)、对于收到的请求,给予确认响应。
      (5)、校验出包有错,丢弃报文段,不响应。
      (6)、对失序数据进行重新排序,发送于客户端。
      (7)、能够丢弃重复数据。
      (8)、流量控制。TCP连接的两端都有缓存大小控制,接收端只允许发送端发送自己缓存剩余大小的数据。有效防止缓存溢出。
      (9)、拥塞控制。当网络阻塞时,减少数据的发送。
JAVA面试——TCP与HTTP
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

9、如何理解HTTP协议的无状态性。

       HTTP协议是无状态的,指的是HTTP协议对于事务处理没有记忆功能,服务器不知道客户端是什么状态。相当于,打开一个服务器上的网页与上一次打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不代表HTTP使用的是UDP协议(无连接)。

10、简述Http请求get和post的区别以及数据包格式。

    ▶ GET请求可被缓存,POST请求不能被缓存。
    ▶ GET请求被保留着浏览器历史记录中,POST请求不会被保留。
    ▶ GET请求能被收藏至书签中,POST请求不能被收藏至书签。
    ▶ GET请求不应在处理敏感数据时使用,POST可以用户处理敏感数据。
    ▶ GET请求有长度限制,POST请求没有长度限制。
    ▶POST不限制提交的数据类型,所以POST可以提交文件到服务器。
    数据包格式 == TCP头结构

11、HTTP有哪些method。

      ★ GET:获取资源。
      ★ POST:表单提交。
      ★ HEAD:获取报头信息,HEAD 方法与 GET 方法类似,但并不会返回响应主体。
      ★ PUT 与PATCH:更新资源,PUT 对后台来说 PUT 方法的参数是一个完整的资源对象,它包含了对象的所有字段,PATCH 对后台来说 PATCH 方法的参数只包含我们需要修改的资源对象的字段。
      ★ DELETE:删除资源。
      ★ OPTIONS:获取目标资源所支持的通信选项,使用 OPTIONS 方法对服务器发起请求,以检测服务器支持哪些 HTTP 方法。

12、简述HTTP请求的报文格式。

        客户端与服务端通信时传输的内容我们称之为报文。
        客户端发送给服务器的称为”请求报文“,服务器发送给客户端的称为”响应报文“。
         JAVA面试——TCP与HTTP
                                                                        图3 POST请求 报文格式
    JAVA面试——TCP与HTTP
                                                                        图4  GET请求 报文格式
JAVA面试——TCP与HTTP
                                                                             图5 报文响应格式

13、HTTP的长连接是什么意思。

       长连接是指客户端与服务端建立连接后,不会因完成了一次请求后,它们之间的连接主动关闭。后续的读写操作会继续使用这个链接。 如果一个连接两小时内都没有任何动作,服务器会向客户端发送一个探测报文段、根据客户端主机相应探测4个客户端状态,①、客户端正常时,且服务器可达。此时客户端TCP响应正常,服务器将定时器复位。②、客户端已经崩溃,并且关闭或正在重启,客户端不能响应TCP,服务器将无法收到客户端对探测器的响应。服务器总共发送10个这样的探测,每间隔75秒。如服务器没有收到任何响应,他就认为客户端已经关闭并终止连接。③、客户端崩溃,但已重启。服务器将对其保持探测响应,这个响应是一个复位,使得服务器终止这个连接。④、 客户机正常运行,但是服务器不可达。这种与②类。
       由上可以看出,长连接可以省去较多的TCP建立和关闭操作,减少浪费,节约时间。对于频繁请求资源的客户端适合使用长连接。在长连接的应用场景下,client端一般不会主动关闭连接,当client与server之间的连接一直不关闭,随着客户端连接越来越多,server会保持过多连接。这时候server端需要采取一些策略,如关闭一些长时间没有请求发生的连接,这样可以避免一些恶意连接导致server端服务受损;如果条件允许则可以限制每个客户端的最大长连接数,这样可以完全避免恶意的客户端拖垮整体后端服务,例如:数据库的连接用长连接。

14、HTTPS的加密方式是什么,讲讲整个加密解密流程。

 加密方式: 1)、对称密码算法:指加密和解密使用相同的**,速度高,可加密内容较大,用来加密会话过程中的消息。典型算法DES、AES、RC5、IDEA(分组加密)RC4。
                    2)、非对称密码算法:又称为公钥加密算法,是指加密和解密使用不同的**,加密速度较慢,但能提供更好的身份认证技术,用来加密对称加密的**(公开的**用于加密,私有的**用于解密)典型的算法RSA、DSA、DH。
                   3)、散列算法:将文件内容通过此算法加密变成固定长度的值(散列值),这个过程可以使用**也可以不使用。这种散列变化是不可逆的,也就是说不能从散列值编程原文,因此散列变化通道常用语验证原文是否被篡改。典型的算法MD5、SHA、BASE64、CRC等。
注意:SSL协议在建立链路时,SSL首先对对称加密的**进行对公加密,链路建立好之后,SSL对传输内容使用对称加密

 SSL加密过程:参考15问题图7 双向认证:  单向认证作为了解加密过程简化流程。
JAVA面试——TCP与HTTP
                                                          图6  单向认证
   第三步:客户端使用服务端返回的信息验证服务器的合法性,包括:
                 1)、证书是否过期。
                 2)、发布服务器证书的CA是否可靠。
                 3)、返回的公钥是否能正确解开返回证书中的数字签名。
                 4)、服务器证书上的域名是否和服务器实际域名相匹配。

15、Http和Https的三次握手有什么区别。

       题目2中所说的握手为HTTP握手的流程,Https在Http的基础上加入了SSL/TSL协议,SSL依靠证书来验证服务器的身份,并为服务器与浏览器之间的通信加密。下图为HTTPS的握手流程。
       JAVA面试——TCP与HTTP
                                                             图7 双向认证

16、什么是分块传送。

       (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) 错误,中断请求。

17、Session和cookie的区别。

       (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。

18、DNS使用的协议(既使用TCP也是用UDP)?

       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查询包。

19、TCP粘包和拆包产生的原因

       ①、应用程序写入数据的字节大小大于套接字发送缓冲区的大小。
       ②、进行MSS大小的TCP分段。MSS是最大报文段长度的缩写。MSS是TCP报文段中的数据字段的最大长度。数据字段加上TCP首部才等于整个的TCP报文段。所以MSS并不是TCP报文段的最大长度,而是:MSS=TCP报文段长度-TCP首部长度
       ③、以太网的payload大于MTU进行IP分片。MTU指:一种通信协议的某一层上面所能通过的最大数据包大小。如果IP层有一个数据包要传,而且数据的长度比链路层的MTU大,那么IP层就会进行分片,把数据包分成托干片,让每一片都不超过MTU。注意,IP分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

解决办法:¤  消息定长。例如100字节。
                  ¤  在包尾部增加回车或者空格符等特殊字符进行分割,典型的如FTP协议
                  ¤  将消息分为消息头和消息尾。
                  ¤  其它复杂的协议,如RTMP协议等。