当前位置: 代码迷 >> 综合 >> java面试必备--JAVA基础篇(十五) 之 WebSocket
  详细解决方案

java面试必备--JAVA基础篇(十五) 之 WebSocket

热度:113   发布时间:2023-09-28 21:26:29.0

       相信很多同行小伙伴会因为许多原因想跳槽,不论是干得不开心还是想跳槽涨薪,在如此内卷的行业,我们都面临着“面试造火箭,上班拧螺丝”的局面,鉴于当前形势博主呕心沥血整理的干货满满的造火箭的技巧来了,本博主花费2个月时间,整理归纳java全生态知识体系常见面试题!总字数高达百万! 干货满满,每天更新,关注我,不迷路,用强大的归纳总结,全新全细致的讲解来留住各位猿友的关注,希望能够帮助各位猿友在应付面试笔试上!当然如有归纳总结错误之处请各位指出修正!如有侵权请联系博主QQ1062141499!


目录

1 Java中的Socket是什么?

2 为什么你们项目组中使用WebSocket技术

3 UDP和TCP协议的概念

4 什么是WebSocket?

5 全双工通讯协议的概念?

6 WebSocket和Socket的区别是什么?

7 HTTP与WebSocket的区别?

8 WebSocket中的常用注解有哪些?

9 TCP和UDP区别

10 基于TCP和UDP的Socket编程的主要步骤

11 TCP与HTTP的区别

12 -TCP为什么要三次握手,两次不行吗?为什么?

13 说一下TCP粘包是怎么产生的?

14  什么是TCP粘包?怎么解决这个问题

15 TCP协议可靠性是如何保证之滑动窗口,超时重发,序列号确认应答信号

16 TCP的三次握手与四次挥手理解

17 TCP、UDP的拥塞控制,流量控制

18 深入理解HTTPS工作原理

19 OSI的七层模型都有哪些?

20  HTTP和HTTPS区别

21 HTTP的长连接和短连接区别

22  HTTP/1.1与HTTP/1.0的区别

23 常见的HTTP协议状态码?

24 HTTP请求行、请求头、请求体详解


1 Java中的Socket是什么?

  • Socket 也称作"套接字",用于描述 IP 地址和端口,是一个通信链的句柄,是应用层与传输层之间的桥梁
  • 应用程序可以通过 Socket 向网络发出请求或应答网络请求
  • 网络应用程序位于应用层,TCP 和 UDP 属于传输层协议,在应用层和传输层之间,使用 Socket 来进行连接
  • Socket 是传输层供给应用层的编程接口
  • Socket 编程可以开发客户端和服务器应用程序,可以在本地网络上进行通信,也可通过公网 Internet 在通信

2 为什么你们项目组中使用WebSocket技术

      当我们在处理页面数据自动更新的时候,在使用js不断的请求服务器,查看是否有新数据,如果有就获取到新数据,进行对页面信息的更新,但是当页面长时间没有更新数据时,这样就会存在资源浪费的情况,所以才会使用WebSocket来解决。

3 UDP和TCP协议的概念

     TCP是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送;而UDP则不为IP提供可靠性、流控或差错恢复功能。一般来说,TCP对应的是可靠性要求高的应用,而UDP对应的则是可靠性要求低、传输经济的应用。

4 什么是WebSocket?

      WebSocket是HTML5一种新的协议,WebSocket是真正实现了全双工通信的服务器向客户端推的互联网技术,是一种在单个TCP连接上进行全双工通讯协议。

5 全双工通讯协议的概念?

     全双工是通讯传输的一个术语。通信允许数据在两个方向上同时传输,他在能力上相当于两个单工通信方式的结合。全双工指可以同时进行信号的双向传输。

     全双工是:例如我们使用的手机就是全双工,在同一时刻两个用户可以同时给对方传送数据

     半双工:例如我们使用的对讲机,当A方按住通话按钮才可以向B方传送数据,B方也是,在同一时 刻只有一个用户能够传送数据(A/用户都可以传递信息,但是不能够同时传递)

     单工:例如我们看电视时,我们只能接收对方发送的信息,不能够给对方传递信息;

java面试必备--JAVA基础篇(十五) 之 WebSocket

6 WebSocket和Socket的区别是什么?

     Socket是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口。而WebSocket则不同,它是一个完整的应用层协议,包含一套标准的API。

7 HTTP与WebSocket的区别?

     HTTP协议是短链接,因为请求之后,都会关闭连接,下次重新请求数据,需要再次打开连接。WebSocket协议是一种长连接,只需要通过一次请求来初始化链接,然后所有的请求和响应都是通过这个TCP链接进行通信。

8 WebSocket中的常用注解有哪些?

     @ServerEndpoint 类似与servlet中的 RequestMapping

     @OnOpen类似与servlet中的 init()初始化

     @OnClose类似与servlet中的destroy() 销毁

      @OnMessage类似于servlet中的service请求 (意思就是发送数据的方式 @doPost() /                 @doGet() 组合)*

9 TCP和UDP区别

     TCP (Transmission ControlProtocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,完成第四层传输层所指定的功能。

     UDP (User Datagram Protoco 用户数据报协议),是OSI(Open System Interconnection,开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。

      TCP和UDP是OSI模型中的运输层中的协议。TCP提供可靠的通信传输,而UDP则常被用于让广播和细节控制交给应用的通信传输。

两者的区别大致如下:

?       TCP面向连接,UDP面向非连接即发送数据前不需要建立链接;

?       TCP提供可靠的服务(数据传输),UDP无法保证;

?       TCP面向字节流,UDP面向报文;

?       TCP数据传输慢,UDP数据传输快;

10 基于TCP和UDP的Socket编程的主要步骤

  • JDK在java.net包中为TCP和UDP两种通信协议提供了相应的Socket编程类
  • TCP协议,服务端对应ServerSocket,客户端对应Socket
  • UDP协议对应DatagramSocket
  • 基于TCP协议创建的套接字可以叫做流套接字,服务器端相当于一个监听器,用来监听端口,服务器与客服端之间的通讯都是输入输出流来实现的
  • 基于UDP协议的套接字就是数据报套接字,客户端和服务端都要先构造好相应的数据包

     基于TCP协议的Socket编程的主要步骤

服务端

  • 指定本地的端口创建ServerSocket实例,用来监听指定端口的连接请求
  • 通过accept()方法返回的Socket实例,建立了一个和客户端的新连接
  • 通过Sockect实例获取InputStream和OutputStream读写数据
  • 数据传输结束,调用socket实例的close()方法关闭连接

客户端

  • 指定的远程服务器IP地址和端口创建Socket实例
  • 通过Socket实例获取InputStream和OutputStream来进行数据的读写
  • 数据传输结束,调用socket实例的close()方法关闭连接

       基于 UDP 协议的 Socket 编程的主要步骤

服务端

  • 指定本地端口创建DatagramSocket实例
  • 通过字节数组,创建DatagramPacket实例,调用DatagramSocket实例的receive()方法,用DatagramPacket实例来接收数据
  • 设置DatagramPacket实例返回的数据,调用DatagramSocket实例的send()方法来发送数据
  • 数据传输完成,调用DatagramSocket实例的close()方法

客户端

  • 创建DatagramSocket实例
  • 通过IP地址端口和数据创建DatagramSocket实例,调用DatagramSocket实例send()方法发送数据包
  • 通过字节数组创建DatagramSocket实例,调用DatagramSocket实例receive()方法接受数据包
  • 数据传输完成,调用DatagramSocket实例的close()方法

11 TCP与HTTP的区别

     TCP连接:手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。

     建立起一个TCP连接需要经过“三次握手

     TCP提供一种面向连接的、可靠的字节流服务。面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据包之前必须先建立一个TCP连接。这一过程与打电话很相似,先拨号振铃,等待对方摘机说“喂”,然后才说明是谁。在一个TCP连接中,仅有两方进行彼此通信。广播和多播不能用于TCP。

      在数据正确性与合法性上,TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和;同时可以使用md5认证对数据进行加密。

     在保证可靠性上,采用超时重传和捎带确认机制。

     在流量控制上,采用滑动窗口协议,协议中规定,对于窗口内未经确认的分组需要重传。

HTTP连接HTTP协议即超文本传送协议,是web联网的基础,也是手机联网常用的协议之一。

HTTP协议是建立在TCP协议之上的一种应用。

HTTP最显著的特点时客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。

       HTTP在每次请求结束后都会主动释放连接,所以为了保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的做法时客户端每隔一段时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端在线,若服务器长时间收不到客户端的请求,则认为下线,若客户端长时间不收到服务器的回复,则认为网络断开。

TCP和HTTP的不同:

  1. TCP是底层协议,定义的是数据传输和连接方式的规范。
  2. HTTP是应用层协议,定义的是传输数据的内容的规范。

12 -TCP为什么要三次握手,两次不行吗?为什么?

       如果采用两次握手,那么只要服务器发出确认数据包就会建立连接,但由于客户端此时并未响应服务器端的请求,那此时服务器端就会一直在等待客户端,这样服务器端就白白浪费了一定的资源。若采用三次握手,服务器端没有收到来自客户端的再此确认,则就会知道客户端并没有要求建立请求,就不会浪费服务器的资源。

  • 两次握手只能保证单向连接是畅通的。

        Step1       A -> B : 你好,B。

        Step2       B -> A : 收到。你好,A。

        这样的两次握手过程, A 向 B 打招呼得到了回应,即 A 向 B 发送数据,B 是可以收到的。

但是 B 向 A 打招呼,A 还没有回应,B 没有收到 A 的反馈,无法确保 A 可以收到 B 发送的数据。

  • 只有经过第三次握手,才能确保双向都可以接收到对方的发送的 数据

       Step3       A -> B : 收到,B。

       这样 B 才能确定 A 也可以收到 B 发送给 A 的数据。

13 说一下TCP粘包是怎么产生的?

     1、什么是 TCP 粘包

           发送方发送的多个数据包,到接收方缓冲区首尾相连,粘成一包,被接收。

      2、原因

  •       发送端需要等缓冲区满才发送。如 TCP 协议默认使用 Nagle 算法可能会把多个数据包一次发送到接收方
  •       接收方不及时接收缓冲区的包,造成多个包接收。如应用程读取缓存中的数据包的速度小于接收数据包的速度,缓存中的多个数据包会被应用程序当成一个包一次读取

    3、处理方法

  •      发送方使用 TCP_NODELAY 选项来关闭 Nagle 算法
  •      数据包增加开始符和结束,应用程序读取、区分数据包
  •       在数据包的头部定义整个数据包的长度,应用程序先读取数据包的长度,然后读取整个长度的包字节数据,保证读取的是单个包且完整

14  什么是TCP粘包?怎么解决这个问题

       在socket网络编程中,都是端到端通信,由客户端端口+服务端端口+客户端IP+服务端IP+传输协议组成的五元组可以明确的标识一条连接。在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须使用高效科学的拆包机制来分辨这些数据。

     1.Q:什么是TCP粘包问题?

      TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。

     2.Q:造成TCP粘包的原因

     (1)发送方原因

        TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:

  1.    只有上一个分组得到确认,才会发送下一个分组
  2.    收集多个小分组,在一个确认到来时一起发送

      Nagle算法造成了发送方可能会出现粘包问题

   (2)接收方原因

       TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。

3.Q:什么时候需要处理粘包现象?

  1. 如果发送方发送的多组数据本来就是同一块数据的不同部分,比如说一个文件被分成多个部分发送,这时当然不需要处理粘包现象
  2. 如果多个分组毫不相干,甚至是并列关系,那么这个时候就一定要处理粘包现象了

4.Q:如何处理粘包现象?

  (1)发送方

      对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法。

(2)接收方

        接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。

(2)应用层

       应用层的解决办法简单可行,不仅能解决接收方的粘包问题,还可以解决发送方的粘包问题。

解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成,但是如何判断每条数据的长度呢?

  1. 格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。
  2. 发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。

5.Q:UDP会不会产生粘包问题呢?

      TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。

      UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包问题。

      举个例子:有三个数据包,大小分别为2k、4k、6k,如果采用UDP发送的话,不管接受方的接收缓存有多大,我们必须要进行至少三次以上的发送才能把数据包发送完,但是使用TCP协议发送的话,我们只需要接受方的接收缓存有12k的大小,就可以一次把这3个数据包全部发送完毕。

15 TCP协议可靠性是如何保证之滑动窗口,超时重发,序列号确认应答信号

     TCP 是一种提供可靠性交付的协议。

     也就是说,通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。

但是在网络中相连两端之间的介质,是复杂的,并不确保数据的可靠性交付,那么 TCP 是怎么样解决问题的?

    TCP 是通过下面几个特性保证数据传输的可靠性:

  • 序列号和确认应答信号
  • 超时重发控制
  • 连接管理
  • 滑动窗口控制
  • 流量控制
  • 拥塞控制

通过序列号和确认应答信号提高可靠性

      如下图,在 TCP 中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知,这个消息叫做确认应答(ACK)。当发送端将数据发出之后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端。反之,则数据丢失的可能性很大。

 

java面试必备--JAVA基础篇(十五) 之 WebSocket

      但是,如果在一定时间内发送端都没有得到确认应答ACK,发送端就会认为数据丢失,并进行数据重发。所以,即使产生了丢包,TCP仍然能保证数据能够到达对端,实现可靠的传输。

发送端确认应答ACK,主要分两种情况:

  • 1. 发送端发送的数据丢包

 java面试必备--JAVA基础篇(十五) 之 WebSocket

  • 上图中的主机A发出数据后因为网络拥堵等原因导致了丢包,数据无法达到主机B,此时,主机A如果在一个特定的时间间隔内都没收到主机B的ACK,则会将数据进行重发
  • 2. 接收端发送的确认应答ACK丢包或延迟

 java面试必备--JAVA基础篇(十五) 之 WebSocket

 

  • 这个图中主机A的数据正常发送到主机B,但由于网络堵塞等原因,主机B的ACK没有达到主机A。主机A在一定时间间隔内始终没收到ACK,则会重发这个数据。
  • 此时,主机B收到数据后就会再次发送ACK,但是由于主机B已经接收过1-1000的数据,所以当再有相同数据达到它时就会放弃这个数据。

     此外,也有可能因为一些其他原因导致ACK延迟到达,在源主机重发数据以后才到达的情况也屡见不鲜。此时,源主机只要按照机制重发数据即可。

      虽然目标主机通过重发数据可以提供可靠的传输,但是对于目标主机来说,反复收到相同的数据可能会是一个”灾难“,既浪费网络资源,还要耗资源对它处理。

      所以,我们需要一种机制来识别是否已经接收到了这个数据包、又能够判断数据包是否需要接收。

      目标主机反复收到相同数据是不可取的,为了保持数据的一致性,目标主机必须扔掉重复的数据包,那么怎么判断该数据包是已经重复收取过呢? 为此我们引入了序列号

       序列号是按照顺序给发送数据的每一个字节(8位字节)都标上号码的编号。接收端查询接收数据 TCP 首部中的序列号和数据的长度,将自己下一步应该接收的序列号作为确认应答返送回去。通过序列号和确认应答号,TCP 能够识别是否已经接收数据,又能够判断是否需要接收,从而实现可靠传输。

        所以,通过序列号,上面说的**“确认应答ACK处理”, “重发控制”,“重复控制”**都能实现了。

超时重发如何确定呢?

  • 重发超时是指在重发数据之前,等待确认应答到来的那个特定时间间隔。如果超过这个时间仍未收到确认应答,发送端将进行数据重发。
  • 最理想的是,找到一个最小时间,它能保证“确认应答一定能在这个时间内返回”。
  • TCP 要求不论处在何种网络环境下都要提供高性能通信,并且无论网络拥堵情况发生何种变化,都必须保持这一特性。为此,它在每次发包时都会计算往返时间(RTT Round Trip Time)及其偏差(RTT波动的时间,也叫抖动)。将这个往返时间和偏差时间相加,重发超时的时间就是比这个总和要稍大一点的值。
  • 重发超时既要考虑RTT往返时间,又要考虑网络抖动的偏差,如下图所示,网络网络环境不同可能会造成RTT大幅度摆动,TCP/IP的目的就是即使在这种环境下也能进行控制,不浪费网络流量。

java面试必备--JAVA基础篇(十五) 之 WebSocket

  • 在 BSD 的 Unix 以及 Windows 系统中,超时都以0.5秒为单位进行控制,因此重发超时都是0.5秒的整数倍。不过,最初其重发超时的默认值一般设置为6秒左右。
  • 数据被重发之后若还是收不到确认应答,则进行再次发送。此时,等待确认应答的时间将会以2倍、4倍的指数函数延长。
  • 此外,数据也不会被无限、反复地重发。达到一定重发次数之后,如果仍没有任何确认应答返回,就会判断为网络或对端主机发生了异常,强制关闭连接。并且通知应用通信异常强行终止。

连接管理

     TCP面向连接的通信协议,面向连接是指在数据通信之前先做好通信两端之间的准备工作。

     因此,在数据通信之前,会通过TCP首部发送一个SYN包作为建立连接和等待确认应答,如果对端发来确认应答ACK,则认为可以进行通信,否则如果对端没有发送正确的ACK应答,那么就不会通信。

      另外通信完毕需要发送FIN包来关闭连接

      这就是我们常常说的 三次握手建立连接 和四次挥手关闭连接

    之前也写了一篇 一文彻底搞懂 TCP三次握手、四次挥手过程及原理,大家有兴趣可以去看看,了解TCP连接时如何建立和关闭的

TCP是以段为单位进行数据包的发送的

       在建立 TCP 连接的同时,也可以确定发送数据包的单位,我们也可以称其为**“最大消息长度”(MSS,Max Segment Size)**,也就是一个段。最理想的情况是,最大消息长度正好是 IP 中不会被分片处理的最大数据长度。

     TCP 在传送大量数据时,是以 MSS 的大小将数据进行分割发送。进行重发时也是以 MSS 为单位。

      MSS 在三次握手的时候,在两端主机之间被计算得出。两端的主机在发出建立连接的请求时,会在 TCP 首部中写入 MSS 选项,告诉对方自己的接口能够适应的 MSS 的大小。然后会在两者之间选择一个较小的值投入使用。

 java面试必备--JAVA基础篇(十五) 之 WebSocket

     上图的是TCPdump抓包的信息,在三次握手建立连接时,大家都交换了对方的MSS,目的是告诉对方,我能适应每次TCP数据传输单位最大是多少,后面通信双方就会按照这个MSS大小作为发送单位发送数据,以上图为例,TCP每次传输最多不会超过65495字节

利用滑动窗口控制提高速度

       上面说了,TCP 以1个段为单位,如果每发送一个段进行一次确认应答,才能进行下一次通信,那这样的传输方式有一个缺点,就是包的往返时间(RTT)越长通信性能就越低。如下图:

java面试必备--JAVA基础篇(十五) 之 WebSocket

      这种方式有点类似于数据库不能并发请求,只能一个挨一个的处理,自然这样的效率肯定是比并发低的

     为解决这个问题,TCP 引入了窗口这个概念。确认应答不是以每个分段来确认,而是以更大的单位进行确认,转发时间将会被大幅地缩短。也就是说,发送端主机,在发送了一个段以后不必要一直等待确认应答,而是继续发送。如下图所示:

java面试必备--JAVA基础篇(十五) 之 WebSocket

      如上图,我们假设窗口大小是4000字节,主机A可以一口气发送把4000字节的序列号发送完毕。这个跟前面每个段接收ACK后才能继续发送新一个段的情况相比,即使RTT变长也不会影响网络的吞吐量。

      窗口大小就是指无需等待确认应答ACK而继续发送数据的最大值

     这种窗口机制实现了使用了大量的缓冲区(Buffer,指的是计算机存储收发数据的的内存空间),通过对多个段同时进行确认应答的功能。

滑动窗口示意图如下:

java面试必备--JAVA基础篇(十五) 之 WebSocket

 

      上面这个图一个段为1000字节,滑动窗口是4个段,在①的状态下,如果收到一个序列号为2000的ACK,那么2001 之前的数据就没必要重发了,这部分的数据可以被过滤掉,滑动窗口成为③的样子。

对于滑动窗口有以下几点特点:

  • 上图中的窗口内的数据即便没有收到确认应答也可以被发送出去。不过,在整个窗口的确认应答没有到达之前,如果其中部分数据出现丢包,那么发送端仍然要负责重传。为此,发送端主机需要设置缓存保留这些待被重传的数据,直到收到他们的确认应答
  • 在滑动窗口以外的部分包括未发送的数据以及已经确认对端已收到的数据。当数据发出后若如期收到确认应答就可以不用再进行重发,此时数据就可以从缓存区清除。
  • 收到确认应答的情况下,将窗口滑动到确认应答中的序列号的位置。这样可以顺序地将多个段同时发送提高通信性能。这种机制也别称为滑动窗口控制

滑动窗口控制与重发控制

在使用了窗口控制中,如果出现了丢包怎么办呢?这里我们还是分两种情况分析:

  • 1.确认应答ACK未能正确返回的情况
  • 在这种情况下,数据是已经被对端主机成功接收了的,是不需要进行重新发送的。
  • 然而,如果在没有使用窗口控制的前提下,没有收到确认应答包的数据包都会被重发。
  • 但是,在使用了窗口控制以后,就如下图所示,某些应答包即使丢失了也无需重发,这也提高了传输效率。

 java面试必备--JAVA基础篇(十五) 之 WebSocket

  • 如上图所示,一个段大小为1000字节,一个窗口大小为6000个字节的情况,主机A连续发送了6000序列号的数据,中间的主机B对1001的ACK丢失了,但是后面的2001的ACK正常返回了,说明前2000的序列号的数据都正常读取了,那么即使1001的ACK丢失也不需要进行数据重发!
  • 所以在窗口控制的机制下,前面的ACK丢失,也能通过下一个ACK进行确认,提高了不少效率。
  • 2.某个报文丢失的情况
  • 如果当接收端主机接收到一个自己应该接收的序列号之外的数据包时,它会一直对当前接收到的数据包返回确认应答包。

java面试必备--JAVA基础篇(十五) 之 WebSocket

      如上图所示,主机A的1001-2000序列号的报文丢失了,它会一直收到来自主机B的一个1001的ACK,这个ACK就像在跟主机A提醒 “我想接收从1001开始的数据”。当主机A连续收到这个1001的确认应答ACK 3后,就会认为数据丢失了,需要重发。

      在滑动窗口比较大的情况下,同一个序列号的确认应答将会被重复不断地返回。而发送端主机如果 连续 3 次 接收到同一个确认应答包,就会将其对应的数据重发,这种机制比之前提到的“超时重发”更加高效,所以被称之为“高速重发控制”

总结

TCP协议在实现传输可靠性上面做了很多:

  • 通过序列号和确认应答信号确保了数据不会重复发送和重复接收。
  • 同时通过超时重发控制保证即使数据包在传输过程中丢失,也能重发保持数据完整。
  • 通过三次握手,四次挥手建立和关闭连接的连接管理保证了端对端的通信可靠性。
  • TCP还使用了滑动窗口控制提高了数据传输效率

16 TCP的三次握手与四次挥手理解

     本文经过借鉴书籍资料、他人博客总结出的知识点,欢迎提问

java面试必备--JAVA基础篇(十五) 之 WebSocket

    序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。

    确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。

    确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

    同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。

    终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接

    PS:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。

 字段

含义

URG

紧急指针是否有效。为1,表示某一位需要被优先处理

ACK

确认号是否有效,一般置为1。

PSH

提示接收端应用程序立即从TCP缓冲区把数据读走。

RST

对方要求重新建立连接,复位。

SYN

请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1

FIN    

希望断开连接。

 三次握手过程理解

 java面试必备--JAVA基础篇(十五) 之 WebSocket

 

第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

四次挥手过程理解 

java面试必备--JAVA基础篇(十五) 之 WebSocket

 

1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2??MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

常见面试题

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

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题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】为什么不能用两次握手进行连接?

答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

       现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

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

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

17 TCP、UDP的拥塞控制,流量控制

     拥塞控制:TCP模块为了防止过多的数据注入网络,使网络中的路由器或链路不致于过载。以此提高网络利用率,降低丢包率,并抱证网络资源对每条数据流的公平性而采取的控制手段。拥塞控制包含四部分内容:慢启动、拥塞避免、快速重传、快速恢复。

     慢启动:  网络传输刚开始时,并不知道网络的实际情况,所以采取一种试探的方式控制数据的发送速率。慢启动阶段,数据的发送速率以指数方式增长,即就是拥塞窗口的增长,每次都是收到确认报文段数量的2倍。可以看出慢启动并不慢,拥塞窗口增长的速度很快。所以,为其设置了一个慢启动门限,当达到门限时,就进入到拥塞避免阶段。

     拥塞避免: 当拥塞窗口的大小采用慢启动方式增长到慢启动门限时,就进入拥塞避免阶段,拥塞避免阶段不再以指数形式增长拥塞窗口,而是每经过一个往返时间RTT就将发送方的拥塞窗口+1, 使其增长速度减缓。按照线性方式增长。如果发生网络拥塞,比如丢包时,就将慢启动门限设为原来的一半,然后将拥塞窗口设置为1,开始执行慢启动算法。(较低的起点,指数级增长)。

      快速重传: 假设发送方发送的报文段分别为: M1,M2,M3,M4,M5,M6 , 当接收方收到M1和M2后,M3报文段丢失,接着收到的M4,M5,M6都不做处理,而是没接收到一个报文段就对M2重复确认,发送方接收到重复的三次确认报文段,就对其后的报文段进行重新发送,而不需要等待超时时间到达。当快速重传后,立即进入到快速恢复阶段。

     快速恢复:将慢启动门限设置为原来的一半,然后将拥塞窗口设置为现在的慢启动门限值,不再执行慢启动算法,而是直接进入拥塞避免阶段。使发送窗口成线性方式增大。

java面试必备--JAVA基础篇(十五) 之 WebSocket

 

      流量控制(滑动窗口协议)TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。【滑动窗口技术存在于数据链路层和传输层。两者有不同的协议,但基本原理相同。区别是一个是发送帧,一个是发送字节数据。接收方的接受窗口告诉发送方本端TCP接受缓冲区还能容纳多少字节,发送方的发送窗口就可以控制发送数据的速度。】

     UDP没有流量控制和拥塞控制,所以在网络拥塞时不会是源主机发送速率降低(对实时通信很有用,比如QQ电话,视频会议等)

18 深入理解HTTPS工作原理

前言

      近几年,互联网发生着翻天覆地的变化,尤其是我们一直习以为常的HTTP协议,在逐渐的被HTTPS协议所取代,在浏览器、搜索引擎、CA机构、大型互联网企业的共同促进下,互联网迎来了“HTTPS加密时代”,HTTPS将在未来的几年内全面取代HTTP成为传输协议的主流。

读完本文,希望你能明白:

  • HTTP通信存在什么问题
  • HTTPS如何改进HTTP存在那些问题
  • HTTPS工作原理是什么

一、什么是HTTPS

         HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

HTTPS主要作用是:

  (1)对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全;

  (2)对网站服务器进行真实身份认证。

     我们经常会在Web的登录页面和购物结算界面等使用HTTPS通信。使用HTTPS通信时,不再用HTTP://,而是改用HTTPs://。另外,当浏览器访问HTTPS通信有效的Web网站时,浏览器的地址栏内会出现一个带锁的标记。对HTTPS的显示方式会因浏览器的不同而有所改变。

java面试必备--JAVA基础篇(十五) 之 WebSocket

二  为什么需要HTTPS

     在HTTP协议中有可能存在信息窃取或身份伪装等安全问题。使用HTTPS通信机制可以有效地防止这些问题,接下来,我们先来了解下

HTTP协议存在的哪些问题:

  • 通信使用明文(不加密),内容可能被窃听

       由于HTTP本身不具备加密的功能,所以也无法做到对通信整体(使用HTTP协议通信的请求和响应的内容)进行加密。即,HTTP报文使用明文(指未经过加密的报文)方式发送

       HTTP明文协议的缺陷是导致数据泄露、数据篡改、流量劫持、钓鱼攻击等安全问题的重要原因。HTTP协议无法加密数据,所有通信数据都在网络中明文“裸奔”。通过网络的嗅探设备及一些技术手段,就可还原HTTP报文内容。

  • 无法证明报文的完整性,所以可能遭篡改

       所谓完整性是指信息的准确度。若无法证明其完整性,通常也就意味着无法判断信息是否准确。由于HTTP协议无法证明通信的报文完整性,因此,在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉。

     换句话说,没有任何办法确认,发出的请求/响应和接收到的请求/响应是前后相同的

  • 不验证通信方的身份,因此有可能遭遇伪装

         HTTP协议中的请求和响应不会对通信方进行确认。在HTTP协议通信时,由于不存在确认通信方的处理步骤,任何人都可以发起请求。另外,服务器只要接收到请求,不管对方是谁都会返回一个响应(但也仅限于发送端的IP地址和端口号没有被Web服务器设定限制访问的前提下)

       HTTP协议无法验证通信方身份,任何人都可以伪造虚假服务器欺骗用户,实现“钓鱼欺诈”,用户无法察觉。

     反观HTTPS协议,它比HTTP协议相比多了以下优势(下文会详细介绍):

  • 数据隐私性:内容经过对称加密,每个连接生成一个唯一的加密密钥
  • 数据完整性:内容传输经过完整性校验
  • 身份认证:第三方无法伪造服务端(客户端)身份

三、HTTPS如何解决HTTP上述问题?

       HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL和TLS协议代替而已。

       通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP

java面试必备--JAVA基础篇(十五) 之 WebSocket

     在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。也就是说HTTP加上加密处理和认证以及完整性保护后即是HTTPS。 

java面试必备--JAVA基础篇(十五) 之 WebSocket

      HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。 

java面试必备--JAVA基础篇(十五) 之 WebSocket

 

1.解决内容可能被窃听的问题——加密

方法1.对称加密

这种方式加密和解密同用一个密钥。加密和解密都会用到密钥。没有密钥就无法对密码解密,反过来说,任何人只要持有密钥就能解密了

以对称加密方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,如果通信被监听那么密钥就可会落人攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。

方法2.非对称加密

公开密钥加密使用一对非对称的密钥。一把叫做私有密钥,另一把叫做公开密钥。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得

使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。

 java面试必备--JAVA基础篇(十五) 之 WebSocket

     非对称加密的特点是信息传输一对多,服务器只需要维持一个私钥就能够和多个客户端进行加密通信。

这种方式有以下缺点:

  • 公钥是公开的,所以针对私钥加密的信息,黑客截获后可以使用公钥进行解密,获取其中的内容;
  • 公钥并不包含服务器的信息,使用非对称加密算法无法确保服务器身份的合法性,存在中间人攻击的风险,服务器发送给客户端的公钥可能在传送过程中被中间人截获并篡改;
  • 使用非对称加密在数据加密解密过程需要消耗一定时间,降低了数据传输效率;

方法3.对称加密+非对称加密(HTTPS采用这种方式)

     使用对称密钥的好处是解密的效率比较快,使用非对称密钥的好处是可以使得传输的内容不能被破解,因为就算你拦截到了数据,但是没有对应的私钥,也是不能破解内容的。就比如说你抢到了一个保险柜,但是没有保险柜的钥匙也不能打开保险柜。那我们就将对称加密与非对称加密结合起来,充分利用两者各自的优势,在交换密钥环节使用非对称加密方式,之后的建立通信交换报文阶段则使用对称加密方式

     具体做法是:发送密文的一方使用对方的公钥进行加密处理“对称的密钥”,然后对方用自己的私钥解密拿到“对称的密钥”,这样可以确保交换的密钥是安全的前提下,使用对称加密方式进行通信。所以,HTTPS采用对称加密和非对称加密两者并用的混合加密机制。

2.解决报文可能遭篡改问题——数字签名

     网络传输过程中需要经过很多中间节点,虽然数据无法被解密,但可能被篡改,那如何校验数据的完整性呢?----校验数字签名。

数字签名有两种功效

  • 能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。
  • 数字签名能确定消息的完整性,证明数据是否未被篡改过。

数字签名如何生成:

java面试必备--JAVA基础篇(十五) 之 WebSocket

      将一段文本先用Hash函数生成消息摘要,然后用发送者的私钥加密生成数字签名,与原文文一起传送给接收者。接下来就是接收者校验数字签名的流程了。

校验数字签名流程

java面试必备--JAVA基础篇(十五) 之 WebSocket

      接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与上一步得到的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。

     假设消息传递在Kobe,James两人之间发生。James将消息连同数字签名一起发送给Kobe,Kobe接收到消息后,通过校验数字签名,就可以验证接收到的消息就是James发送的。当然,这个过程的前提是Kobe知道James的公钥。问题的关键的是,和消息本身一样,公钥不能在不安全的网络中直接发送给Kobe,或者说拿到的公钥如何证明是James的。

       此时就需要引入了证书颁发机构(Certificate Authority,简称CA),CA数量并不多,Kobe客户端内置了所有受信任CA的证书。CA对James的公钥(和其他信息)数字签名后生成证书。

3.解决通信方身份可能被伪装的问题——数字证书

    数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。

java面试必备--JAVA基础篇(十五) 之 WebSocket

我们来介绍一下数字证书认证机构的业务流程:

  • 服务器的运营人员向第三方机构CA提交公钥、组织信息、个人信息(域名)等信息并申请认证;
  • CA通过线上、线下等多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等;
  • 如信息审核通过,CA会向申请者签发认证文件-证书。证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构 CA的信息、有效时间、证书序列号等信息的明文,同时包含一个签名。 其中签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA的私钥对信息摘要进行加密,密文即签名;
  • 客户端 Client 向服务器 Server 发出请求时,Server 返回证书文件;
  • 客户端 Client 读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应 CA的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性,即服务器的公开密钥是值得信赖的。
  • 客户端还会验证证书相关的域名信息、有效时间等信息; 客户端会内置信任CA的证书信息(包含公钥),如果CA不被信任,则找不到对应 CA的证书,证书也会被判定非法。

 四、HTTPS工作流程

     java面试必备--JAVA基础篇(十五) 之 WebSocket

1.Client发起一个HTTPS(比如HTTPs://juejin.im/user/5a9a9cdcf265da238b7d771c)的请求,根据RFC2818的规定,Client知道需要连接Server的443(默认)端口。

2.Server把事先配置好的公钥证书(public key certificate)返回给客户端。

3.Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书)。如果验证通过则继续,不通过则显示警告信息。

4.Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。

5.Server使用自己的私钥(private key)解密这个消息,得到对称密钥。至此,Client和Server双方都持有了相同的对称密钥。

6.Server使用对称密钥加密“明文内容A”,发送给Client。

7.Client使用对称密钥解密响应的密文,得到“明文内容A”。

8.Client再次发起HTTPS的请求,使用对称密钥加密请求的“明文内容B”,然后Server使用对称密钥解密密文,得到“明文内容B” 

五、HTTP 与 HTTPS 的区别

  • HTTP 是明文传输协议,HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。

java面试必备--JAVA基础篇(十五) 之 WebSocket

 

关于安全性,用最简单的比喻形容两者的关系就是卡车运货,HTTP下的运货车是敞篷的,货物都是暴露的。而HTTPs则是封闭集装箱车,安全性自然提升不少。

  • HTTPS比HTTP更加安全,对搜索引擎更友好,利于SEO,谷歌、百度优先索引HTTPS网页;
  • HTTPS需要用到SSL证书,而HTTP不用;
  • HTTPS标准端口443,HTTP标准端口80;
  • HTTPS基于传输层,HTTP基于应用层;
  • HTTPS在浏览器显示绿色安全锁,HTTP没有显示;

 

六、为何不所有的网站都使用HTTPS

       既然HTTPS那么安全可靠,那为何不所有的Web网站都使用HTTPS?

       首先,很多人还是会觉得HTTPS实施有门槛,这个门槛在于需要权威CA颁发的SSL证书。从证书的选择、购买到部署,传统的模式下都会比较耗时耗力。

      其次,HTTPS普遍认为性能消耗要大于HTTP,因为与纯文本通信相比,加密通信会消耗更多的CPU及内存资源。如果每次通信都加密,会消耗相当多的资源,平摊到一台计算机上时,能够处理的请求数量必定也会随之减少。但事实并非如此,用户可以通过性能优化、把证书部署在SLB或CDN,来解决此问题。举个实际的例子,“双十一”期间,全站HTTPS的淘宝、天猫依然保证了网站和移动端的访问、浏览、交易等操作的顺畅、平滑。通过测试发现,经过优化后的许多页面性能与HTTP持平甚至还有小幅提升,因此HTTPS经过优化之后其实并不慢。

        除此之外,想要节约购买证书的开销也是原因之一。要进行HTTPS通信,证书是必不可少的。而使用的证书必须向认证机构(CA)购买。

       最后是安全意识。相比国内,国外互联网行业的安全意识和技术应用相对成熟,HTTPS部署趋势是由社会、企业、政府共同去推动的。

19 OSI的七层模型都有哪些?

?       物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。

?       数据链路层:负责建立和管理节点间的链路。

?       网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。

?       传输层:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。

?       会话层:向两个实体的表示层提供建立和使用连接的方法。

?       表示层:处理用户信息的表示问题,如编码、数据格式转换和加密解密等。

?       应用层:直接向用户提供服务,完成用户希望在网络上完成的各种工作。

20  HTTP和HTTPS区别

java面试必备--JAVA基础篇(十五) 之 WebSocket

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

  为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

一、HTTP和HTTPS的基本概念

  HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

  HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

  HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

二、HTTP与HTTPS有什么区别?

  HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比HTTP协议安全。

HTTPS和HTTP的区别主要如下:

1、HTTPs协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

2、HTTP是超文本传输协议,信息是明文传输,HTTPs则是具有安全性的ssl加密传输协议

3、HTTP和HTTPs使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443

4、HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。

三、HTTPS的工作原理

  我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。

 java面试必备--JAVA基础篇(十五) 之 WebSocket

 客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤,如图所示。

  (1)客户使用HTTPs的URL访问Web服务器,要求与Web服务器建立SSL连接。

  (2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。

  (3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。

  (4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。

  (5)Web服务器利用自己的私钥解密出会话密钥。

  (6)Web服务器利用会话密钥加密与客户端之间的通信。

  java面试必备--JAVA基础篇(十五) 之 WebSocket 

四、HTTPS的优点

  尽管HTTPS并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击,但HTTPS仍是现行架构下最安全的解决方案,主要有以下几个好处:

  (1)使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;

  (2)HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比HTTP协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。

  (3)HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

  (4)谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。

五、HTTPS的缺点

  虽然说HTTPS有很大的优势,但其相对来说,还是存在不足之处的:

  (1)HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;

  (2)HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;

  (3)SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。

  (4)SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。

  (5)HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。

六、HTTP切换到HTTPS

  如果需要将网站从HTTP切换到HTTPs到底该如何实现呢?

     这里需要将页面中所有的链接,例如js,css,图片等等链接都由HTTP改为HTTPs。例如:HTTP://www.baidu.com改为HTTPs://www.baidu.com

  BTW,这里虽然将HTTP切换为了HTTPs,还是建议保留HTTP。所以我们在切换的时候可以做HTTP和HTTPs的兼容,具体实现方式是,去掉页面链接中的HTTP头部,这样可以自动匹配HTTP头和HTTPs头。例如:将HTTP://www.baidu.com改为//www.baidu.com。然后当用户从HTTP的入口进入访问页面时,页面就是HTTP,如果用户是从HTTPs的入口进入访问页面,页面即使HTTPs的。

21 HTTP的长连接和短连接区别

      HTTP协议有HTTP/1.0版本和HTTP/1.1版本。HTTP1.1默认保持长连接(HTTPpersistentconnection,也翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接。

     在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接

22  HTTP/1.1与HTTP/1.0的区别

可扩展性

    a) HTTP/1.1在消息中增加版本号,用于兼容性判断。

    b) HTTP/1.1增加了OPTIONS方法,它允许客户端获取一个服务器支持的方法列表。

   c) 为了与未来的协议规范兼容,HTTP/1.1在请求消息中包含了Upgrade头域,通过该头域,客户端可以让服务器知道它能够支持的其它备用通信协议,服务器可以据此进行协议切换,使用备用协议与客户端进行通信。

2  缓存

        在HTTP/1.0中,使用Expire头域来判断资源的fresh或stale,并使用条件请求(conditionalrequest)来判断资源是否仍有效。HTTP/1.1在1.0的基础上加入了一些cache的新特性,当缓存对象的Age超过Expire时变为stale对象,cache不需要直接抛弃stale对象,而是与源服务器进行重新激活(revalidation)。

3  带宽优化

        HTTP/1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了。例如,客户端只需要显示一个文档的部分内容,又比如下载大文件时需要支持断点续传功能,而不是在发生断连后不得不重新下载完整的包。

       HTTP/1.1中在请求消息中引入了range头域,它允许只请求资源的某个部分。在响应消息中Content-Range头域声明了返回的这部分对象的偏移值和长度。如果服务器相应地返回了对象所请求范围的内容,则响应码为206(PartialContent),它可以防止Cache将响应误以为是完整的一个对象。

        另外一种情况是请求消息中如果包含比较大的实体内容,但不确定服务器是否能够接收该请求(如是否有权限),此时若贸然发出带实体的请求,如果被拒绝也会浪费带宽。

      HTTP/1.1加入了一个新的状态码100(Continue)。客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。注意,HTTP/1.0的客户端不支持100响应码。但可以让客户端在请求消息中加入Expect头域,并将它的值设置为100-continue。节省带宽资源的一个非常有效的做法就是压缩要传送的数据。Content-Encoding是对消息进行端到端(end-to-end)的编码,它可能是资源在服务器上保存的固有格式(如jpeg图片格式);在请求消息中加入Accept-Encoding头域,它可以告诉服务器客户端能够解码的编码方式。

4  长连接

      HTTP/1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。此外,由于大多数网页的流量都比较小,一次TCP连接很少能通过slow-start区,不利于提高带宽利用率。

       HTTP1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。例如:一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。HTTP1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户

      端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。

5  消息传递

      HTTP消息中可以包含任意长度的实体,通常它们使用Content-Length来给出消息结束标志。但是,对于很多动态产生的响应,只能通过缓冲完整的消息来判断消息的大小,但这样做会加大延迟。如果不使用长连接,还可以通过连接关闭的信号来判定一个消息的结束。

       HTTP/1.1中引入了Chunkedtransfer-coding来解决上面这个问题,发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后用一个零长度的块作为消息结束的标志。这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。

      在HTTP/1.0中,有一个Content-MD5的头域,要计算这个头域需要发送方缓冲完整个消息后才能进行。而HTTP/1.1中,采用chunked分块传递的消息在最后一个块(零长度)结束之后会再传递一个拖尾(trailer),它包含一个或多个头域,这些头域是发送方在传递完所有块之后再计算出值的。发送方会在消息中包含一个Trailer头域告诉接收方这个拖尾的存在。

6  Host头域

       在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homedWebServers),并且它们共享一个IP地址。

       HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400BadRequest)。此外,服务器应该接受以绝对路径标记的资源请求。

7  错误提示

        HTTP/1.0中只定义了16个状态响应码,对错误或警告的提示不够具体。HTTP/1.1引入了一个Warning头域,增加对错误或警告信息的描述。

     此外,在HTTP/1.1中新增了24个状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

23 常见的HTTP协议状态码?

   2xx:表示请求已被成功接收、理解、接受

  • 200(成功)  服务器已成功处理了请求。这个状态码对servlet是缺省的,如果没有调用setStatus方法的话,就会得到 200
  • 204(无内容)  服务器成功处理了请求,未返回任何内容
  • 205(重置内容) 服务器成功处理了请求,未返回任何内容,重置文档视图,如清除表单内容
  • 206(部分内容)  服务器成功处理了部分 GET 请求

3xx:重定向

  • 300(多种选择)  服务器根据请求可执行多种操作。服务器可根据请求者 来选择一项操作,或提供操作列表供其选择
  • 301(永久移动)  请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置
  • 302(临时移动) 服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。会自动将请求者转到新位置
  • 304(未修改) 自从上次请求后,请求的网页未被修改过,不会返回网页内容
  • 305(使用代理) 请求者只能使用指定的代理访问请求的网页

4xx:客户端错误,请求有语法错误或请求无法实现

  • 400(错误请求) 服务器不理解请求的语法
  • 401(身份验证错误) 此页要求授权
  • 403(禁止) 服务器拒绝请求
  • 404(未找到) 服务器找不到请求的网页
  • 406(不接受) 无法使用请求的内容特性响应请求的网页
  • 408(请求超时) 服务器等候请求时发生超时
  • 414(请求的 URI 过长) 请求的 URI 过长,服务器无法处理

5xx:服务器端错误,无法处理请求

  • 500(服务器内部错误)  服务器遇到错误,无法完成请求。
  • 503(服务不可用) 目前无法使用服务器(由于超载或进行停机维护)。通常,这只是一种暂时的状态。
  • 504(网关超时)  服务器作为网关或代理,未及时从上游服务器接收请求。
  • 505(HTTP 版本不受支持) 服务器不支持请求中所使用的 HTTP 协议版本

24 HTTP请求行、请求头、请求体详解

    HTTP请求报文解剖

    HTTP请求报文由3部分组成(请求行+请求头+请求体):

   下面是一个实际的请求报文:

java面试必备--JAVA基础篇(十五) 之 WebSocket

      ① 是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHTTPMethodFilter,允许你通过“_method”的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了HiddenHTTPMethodFilter后,Spring会根据_method参数指定的值模拟出相应的HTTP方法,这样,就可以使用这些HTTP方法对处理方法进行映射了。

     ② 为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL

     ③ 是协议名称及版本号。

     ④ 是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。

    ⑤ 是报文体,它将一个页面表单中的组件值通过param1=value1&param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/chapter15/user.html? param1=value1&param2=value2”的方式传递请求参数。

对照上面的请求报文,我们把它进一步分解,你可以看到一幅更详细的结构图:

java面试必备--JAVA基础篇(十五) 之 WebSocket 

       HTTPWatch是强大的网页数据分析工具,安装后将集成到Internet Explorer工具栏中。它不用代理服务器或一些复杂的网络监控工具,就能抓取请求及响应的完整信息,包括Cookies、消息头、查询参数、响应报文等,是Web应用开发人员的必备工具。

HTTP请求报文头属性

        报文头属性是什么东西呢?我们不妨以一个小故事来说明吧。

引用

       快到中午了,张三丰不想去食堂吃饭,于是打电话叫外卖:老板,我要一份[鱼香肉丝],要12:30之前给我送过来哦,我在江湖湖公司研发部,叫张三丰。

       这里,你要[鱼香肉丝]相当于HTTP报文体,而“12:30之前送过来”,你叫“张三丰”等信息就相当于HTTP的报文头。它们是一些附属信息,帮忙你和饭店老板顺利完成这次交易。

      请求HTTP报文和响应HTTP报文都拥有若干个报文关属性,它们是为协助客户端及服务端交易的一些附属信息。

常见的HTTP请求报文头属性

Accept

      请求报文可通过一个“Accept”报文头属性告诉服务端 客户端接受什么类型的响应。

如下报文头相当于告诉服务端,俺客户端能够接受的响应类型仅为纯文本数据啊,你丫别发其它什么图片啊,视频啊过来,那样我会歇菜的~~~:

Accept:text/plain 

      Accept属性的值可以为一个或多个MIME类型的值,关于MIME类型,大家请参考:HTTP://en.wikipedia.org/wiki/MIME_type

Cookie

     客户端的Cookie就是通过这个报文头属性传给服务端的哦!如下所示:

Cookie: $Version=1; Skin=new;jsessionid=5F4771183629C9834F8382E23BE13C4C 

      服务端是怎么知道客户端的多个请求是隶属于一个Session呢?注意到后台的那个jsessionid=5F4771183629C9834F8382E23BE13C4C木有?原来就是通过HTTP请求报文头的Cookie属性的jsessionid的值关联起来的!(当然也可以通过重写URL的方式将会话ID附带在每个URL的后面哦)。

Referer

      表示这个请求是从哪个URL过来的,假如你通过google搜索出一个商家的广告页面,你对这个广告页面感兴趣,鼠标一点发送一个请求报文到商家的网站,这个请求报文的Referer报文头属性值就是HTTP://www.google.com。

引用

      唐僧到了西天.

如来问:侬是不是从东土大唐来啊?

唐僧:厉害!你咋知道的!

如来:呵呵,我偷看了你的Referer...

      很多貌似神奇的网页监控软件(如著名的 我要啦),只要在你的网页上放上一段JavaScript,就可以帮你监控流量,全国访问客户的分布情况等报表和图表,其原理就是通过这个Referer及其它一些HTTP报文头工作的。

Cache-Control

       对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。

       如以下设置,相当于让服务端将对应请求返回的响应内容不要在客户端缓存:

Cache-Control: no-cache 

     其它请求报文头属性

参见:HTTP://en.wikipedia.org/wiki/List_of_HTTP_header_fields

如何访问请求报文头

       由于请求报文头是客户端发过来的,服务端当然只能读取了,以下是HTTPServletRequest一些用于读取请求报文头的API:

 //获取请求报文中的属性名称  java.util.Enumeration<java.lang.String> getHeaderNames();  //获取指定名称的报文头属性的值  java.lang.String getHeader(java.lang.String name)   

   由于一些请求报文头属性“太著名”了,因此HTTPServletRequest为它们提供了VIP的API:

//获取报文头中的Cookie(读取Cookie的报文头属性)  Cookie[] getCookies() ;  //获取客户端本地化信息(读取 Accept-Language 的报文头属性)  
java.util.Locale getLocale()   //获取请求报文体的长度(读取Content-Length的报文头属性)  
int getContentLength(); 

HTTPServletRequest可以通过

HTTPSession getSession()  

      获取请求所关联的HTTPSession,其内部的机理是通过读取请求报文头中Cookie属性的JSESSIONID的值,在服务端的一个会话Map中,根据这个JSESSIONID获取对应的HTTPSession的对象。(这样,你就不会觉得HTTPSession很神秘了吧,你自己也可以做一个类似的会话管理 ! )

HTTP响应报文解剖

    HTTP的响应报文也由三部分组成(响应行+响应头+响应体):

    以下是一个实际的HTTP响应报文:

java面试必备--JAVA基础篇(十五) 之 WebSocket

①报文协议及版本;

②状态码及状态描述;

③响应报文头,也是由多个属性组成;

④响应报文体,即我们真正要的“干货”。

响应状态码

和请求报文相比,响应报文多了一个“响应状态码”,它以“清晰明确”的语言告诉客户端本次请求的处理结果。

HTTP的响应状态码由5段组成:

  1. 1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
  2. 2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
  3. 3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
  4. 4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
  5. 5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。

以下是几个常见的状态码:

200 OK

     你最希望看到的,即处理成功!

303 See Other

        我把你redirect到其它的页面,目标的URL通过响应报文头的Location告诉你。

引用

        悟空:师傅给个桃吧,走了一天了!

       唐僧:我哪有桃啊!去王母娘娘那找吧!

304 Not Modified

        告诉客户端,你请求的这个资源至你上次取得后,并没有更改,你直接用你本地的缓存吧,我很忙哦,你能不能少来烦我啊!

404 Not Found

      你最不希望看到的,即找不到页面。如你在google上找到一个页面,点击这个链接返回404,表示这个页面已经被网站删除了,google那边的记录只是美好的回忆。

500 Internal Server Error

       看到这个错误,你就应该查查服务端的日志了,肯定抛出了一堆异常,别睡了,起来改BUG去吧!

        其它的状态码参见:HTTP://en.wikipedia.org/wiki/List_of_HTTP_status_codes

     有些响应码,Web应用服务器会自动给生成。你可以通过HTTPServletResponse的API设置状态码:

   //设置状态码,状态码在HTTPServletResponse中通过一系列的常量预定义了,如SC_ACCEPTED,SC_OK 

void setStatus(int sc)

常见的HTTP响应报文头属性

Cache-Control

      响应输出到客户端后,服务端通过该报文头属告诉客户端如何控制响应内容的缓存。

      下面,的设置让客户端对响应内容缓存3600秒,也即在3600秒内,如果客户再次访问该资源,直接从客户端的缓存中返回内容给客户,不要再从服务端获取(当然,这个功能是靠客户端实现的,服务端只是通过这个属性提示客户端“应该这么做”,做不做,还是决定于客户端,如果是自己宣称支持HTTP的客户端,则就应该这样实现)。

Cache-Control: max-age=3600  

ETag

       一个代表响应服务端资源(如页面)版本的报文头属性,如果某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可以让客户端“更智能”地处理什么时候要从服务端取资源,什么时候可以直接从缓存中返回响应。

     关于ETag的说明,你可以参见:HTTP://en.wikipedia.org/wiki/HTTP_ETag。

        Spring 3.0还专门为此提供了一个org.springframework.web.filter.ShallowEtagHeaderFilter(实现原理很简单,对JSP输出的内容MD5,这样内容有变化ETag就相应变化了),用于生成响应的ETag,因为这东东确实可以帮助减少请求和响应的交互。

下面是一个ETag:

ETag: "737060cd8c284d8af7ad3082f209582d"

Location

        我们在JSP中让页面Redirect到一个某个A页面中,其实是让客户端再发一个请求到A页面,这个需要Redirect到的A页面的URL,其实就是通过响应报文头的Location属性告知客户端的,如下的报文头属性,将使客户端redirect到iteye的首页中:

Location: HTTP://www.iteye.com  

Set-Cookie

       服务端可以设置客户端的Cookie,其原理就是通过这个响应报文头属性实现的:

Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 

     其它HTTP响应报文头属性

   更多其它的HTTP响应头报文,参见:HTTP://en.wikipedia.org/wiki/List_of_HTTP_header_fields

如何写HTTP请求报文头

在服务端可以通过HTTPServletResponse的API写响应报文头的属性:

 //添加一个响应报文头属性  
void setHeader(String name, String value) 

像Cookie,Location这些响应都是有福之人,HTTPServletResponse为它们都提供了VIP版的API:

     //添加Cookie报文头属性  void addCookie(Cookie cookie)   //不但会设置Location的响应报文头,还会生成303的状态码呢,两者天仙配呢  
void sendRedirect(String location)

  相关解决方案