在建立TCP连接时,客户端和服务器之间需要发送三个SYN包,三次握手是为了确认客户端和服务器的发送信息和接受信息是否正常。其实他们是连接指定端口,建立TCP连接并交换序列号(SEQ)和确认号(ACK),交换TCP窗口大小信息。
①第一次握手
客户端向服务器发送一个SYN报文包,同时状态变为SYN_SEND。客户端发送的SYN报文包其中初始序号SEQ为x,首部同步位SYN = 1;这个SYN报文包不携带数据,但占用一个序列号。
②第二次握手
服务器接收到SYN报文包,状态变为SYN_RCVD,同时发送一个自己的SYN包给客户端,里面包含了个ACK的值。服务器发送的SYN报文包其中初始序号为y,指定初始化序列号为ISN(s),ACK的值为1,SYN = 1 ,确认号ack = x + 1(ISN的值+ 1)
③第三次握手
客户端接收到服务器发送的SYN报文包,同时发送一个ACK报文包给服务器,客户端状态变为established;服务器接收到ACK报文包以后状态变为established。其中ACK报文包中,ACK的值为ISN + 1。ack = 1,ACK = y + 1,seq = x + 1。最后发送的确认报文段可以携带数据,不携带数据则不占有序列号。
因为如果是两次握手,就不存在TCP协议数据交换的三次握手的完整性。举个例子,如果现在客户端向服务器发送一个连接包,可是因为延迟问题未能快速发送,然后客户端又发送了一个连接包,连接上了,那么他进行交换完之后释放了连接此时第一次发送的包才让服务器接收到,这时就会认为客户端又向服务器发送了连接请求,又进行连接后才处理第一次的包。这样导致的问题是什么呢?这样会使连接使用的频率增加,频繁的建立连接会浪费资源,也会增加服务器的传输负担。所以需要三次握手的完整性。
半连接顾名思义就是只连接了一半,当客户端向服务器发送第一次连接请求,服务器接收到,但是还没有进行第二次握手返回包到客户端的这个时间段,就是一个半连接。服务器会将这些半连接放在一个半连接队列里。如果半连接队列满了,就会出现丢包现象。在服务器返回确认包去客户端的时候,客户端没有接收到就会重传,每个重传都有自己的重传时间,一般是以指数增加,比如2s、4s、8s…增加。重传次数大于最大重传次数时服务器就会将此半连接删除。
在发送SYN报文包里,ISN会为连接选择一个序号。在三次握手中,客户端和服务器就交换了ISN,ISN随时间而变化,所以每个连接的ISN都不一样。ISN可以看做是一个32比特的计数器。因为如果ISN是固定不变的话,容易给“攻击者”猜到,所以ISN是动态生成的。
第一次握手不可以携带数据,为什么呢?我举个例子,在有“攻击者”攻击服务器的时候是怎么进行的呢?以及DOS/DDOS的实现(后面再讲)?其实就是一个客户端或多个疯狂向服务器发送连接请求,但是携带的是虚拟的IP地址,所以服务器接收后返回数据过去的时候就一直重传,就堆积了许多的半连接在队列里。直到堆满了服务器的半连接队列,就会使服务器崩溃。第一次握手不允许携带数据就是为了避免这样的情况发生,我三次握手一定要确认客户端和服务器是否存在和互连。为什么第三次握手可以携带数据呢?因为在前两次握手上我已经确认客户端和服务器是可以连接和互传的,只是第三次握手是将我可以连接和你服务器讲一下而已,那我客户端可以和你连接,我客户端知道了那我带着数据过去告诉你我们可以连接,顺便处理一下这些数据,也是可以的。
在上一个问题我解释了“攻击”是如何实现的。那可以知道服务器端分配资源是在第二次握手的时候进行的,而客户端的资源是在第三次握手进行的,那就生成了个时间差。就会产生很多“攻击者”让服务器分配资源然后又找不到客户端的存在,就无法进行客户端资源的分配,导致服务器一直在重传。那么如果是正常的SYN传输就会给这些虚拟SYN影响到处理,导致服务器的半连接队列存在太多和挤满,从而形成网络拥挤和服务器瘫痪。典型的SYN攻击就是DOS/DDOS攻击,基本上都是基于洪泛攻击之上。
DOS攻击又名拒绝服务,是一个客户端对服务器使用SYN攻击等手段去影响服务器处理的。又可以理解成单机攻击。
DDOS攻击又名分布式拒绝服务,是多个客户端对服务器使用SYN攻击等手段去影响服务器处理的。又可以理解成多机攻击。黑客通过占用其他人的电脑,然后操控其电脑作为一个客户端去向服务器发送虚拟连接请求。被操纵的电脑被称为“僵尸主机”,DDOS又可以理解为多机攻击。
客户端和服务器都能先发送终止连接包,这里以客户端发送为准。在第一次挥手前双方都处于established状态。
①第一次挥手
客户端向服务器发送一个FIN报文包,客户端的状态变为FIN_WAIT1。发送的FIN报文包(FIN = 1,初始序号SEQ = u).
②第二次挥手
服务器接收到客户端发的FIN报文包,然后向客户端发送一个ACK包,状态变为CLOSE_WAIT。发送的ACK包(ACK = 1,ack确认号 = u + 1,初始序号SEQ = v)
③第三次挥手
服务器向客户端发送一个FIN报文包,状态变为LAST_ACK,发送的FIN报文包(向客户端确认是否是此连接——FIN = 1 ,ACK = 1 , ack确认号 = u + 1 ,初始序号 = w)
④第四次挥手
客户端接收到服务器发送的FIN报文包,然后状态变为TIME_WAIT,经过2MSL时间变为CLOSED,同时向服务器发送一个ACK包,ACK包(ACK = 1 , ack确认号 = w + 1 , 序号SEQ = u + 1),若TCP连接未断开,客户端需要经过2MSL时间才进入CLOSED状态。若断开,客户端就变为CLOSED状态,同时服务器也变为CLOSED状态。
在四次挥手过程中,在第二次挥手完成后,形成半关闭。当对方确认关闭时,然后再关闭剩下的一半。
在请求连接的时候,返回的ACK包里含有:SYN + ACK 报文,ACK报文是用于应答,SYN报文是用于同步。但是在终止连接请求的时候,客户端向服务器发送FIN报文包,服务器向客户端发送ACK包作应答,但是在这时服务器不一定要现在立即就关闭掉此连接,或者还需要处理一下socket再去关闭,所以需要服务器重新再发送FIN包去作为我服务器端的关闭连接请求。所以就需要四次挥手。
MSL是TCP连接里的最大等待时间,也可称为报文段最大寿命,它是任何报文段在被抛弃前存在于网络上的最长时间。2倍的MSL等待是客户端最后的TIME_WAIT状态时候的等待时长,为什么要有这个等待时长呢?因为在最后第四次挥手的时候,发送的ACK确认包有可能还没到达,就需要时间去等待,如果丢失了这个包,就会触发重传FIN包,然后会刷新两倍的MSL等待时间。另一个作用是为了在这2倍的MSL时间里,这个连接的客户端的端口号和IP和服务器的端口号和IP不可被使用。
这个意义就是为了等待最后客户端发送到服务器的ACK包到达。如果在此间ACK包丢失,那么在LAST_ACK状态的服务器就接收不到FIN_ACK包,然后开始重传,重新刷新这个等待时间,直到最后双方都进入CLOSED状态。如果没有了这个等待的时间,那么在客户端发送完ACK包后就进入CLOSED状态,那么如果ACK包丢失了呢?那么服务器就找不到客户端进行冲传,然后就进入异常的连接关闭状态,无法正常的进入连接关闭状态。
总结起来有两个意义:
①为了使客户端最后发送的ACK包到达服务器从而正常断开连接。
②为了防止已断开连接的旧的连接请求出现在本连接内。什么意思呢?就是在客户端发送完最后的ACK包的2MSL时间里,所有的关于在这个连接内的报文段全部删除,就不会出现还有这个连接的连接请求了。
因为什么,在上面已经解释的很清楚了,现在最后总结一下就是为了防止客户端最后发送的ACK包丢失,如果丢失,用来重传ACK包。
HTTP请求是由请求行、消息报头、请求正文组成。
HTTP协议是超文本传输协议,是基于响应与请求模式、无状态的和应用层的协议,基于TCP的连接方式。
①GET:通过获取已经被URL识别的资源来从服务器获取数据。
②POST:向服务器传输数据。
③PUT:向指定的URL地址传输文件。
④DELETE:在指定的URL地址上删除文件。
⑤HEAD:获取报头,但不返回报头正文,通常用于验证URL是否存在。
⑥OPTIONS:用于获取对应URL的HTTP方法。
①GET方法是从服务器中获取数据;POST方法是向服务器传输数据。
②GET方法是通过URL的请求,然后将field = name的形式置于URL之后,中间以“?”作为间隔。多个field = name以“&”相连,URL是可见的;而POST方法是以HTTP协议的post机制去传输数据,过程是不可见的。
③GET方法获取数据的有限的,因为受到URL的长度限制,但是传输速率快;POST方法是可以大量的传输数据,所以上传文件都用POST方法。
④GET方法是比较不安全的,因为在向服务器获取资源的请求中,URL是可见的,一些信息就会暴露出来,比如密码等;而POST方法的传输过程是不可见的,相较于GET方法是更安全的。
⑤GET方法是以ASCll字符去获取数据的,如果是中文字符则会出现乱码现象;而POST方法是以标准字符集去传输数据的,传输中文字符就不会出现乱码。
请求报文和响应报文都是由三部分组成。其中
①请求报文(1)请求行:HTTP版本信息,请求方法,URL
(2)请求报文首部
(3)请求内容实体
②响应报文(1)状态行:状态码,状态码的原因,HTTP信息
(2)响应报文首部
(3)响应内容实体
1xx:指示信息;表示请求被接受,继续处理。
2xx:成功;表示请求被接收,处理,接受。
3xx:重定向;表示请求还需要进行下一步的指令。
4xx:客户端错误;表示客户端语法错误或者请求无法实现。
5xx:服务器端错误;表示服务器未能实现合法的请求。
< 2xx >
200:请求被成功处理
204:请求被成功处理但是没有资源可以被返回
206:请求只访问服务器部分资源,服务器只对这一部分资源执行GET方法
< 3xx >
301:永久性重定向
302:临时性重定向
303:与临时性重定向类似,但是是客户端希望访问此URL时服务器重定向到另一个URL上
304:与重定向无关,是服务器无法实现请求的附带条件,然后返回请求。
307:与临时性重定向类似,但是只能给POST方法使用
< 4xx >
400:客户端报文语法错误
401:请求的认证不通过
403:请求的资源禁止服务器访问,
404:请求的资源不存在,服务器找不到
< 5xx >
500:服务器内部错误
503:服务器正忙
①默认持久连接
即当客户端或者服务器端有一端没有显式提出断开TCP连接,则还可以发送多个请求。
②管线化
客户端可以发送多个请求,而不用等待一个一个去响应。
③断点续传原理
断点续传原理是什么呢?这个技术结合了本地存储和网络存储,去解决因网络连接失败而导致的视频丢失问题。因为DVS(网络视频服务器)不具备存储视频的能力,而NVR(网络视频录像器)具有存储视频的能力,但是NVR有个缺点,就是特别的需要网络的稳定性,当出现网络连接失败,网络中断,丢包,抖动等问题,都会导致视频的丢失,这时候如果重新传送就太浪费资源和时间了,所以出现这个技术,即可在断点(停止点)继续接上上传,而不用重新上传。
①通用的首部字段(即请求报文和响应报文都会用的)
Date:创建报文的时间
Connection:连接的管理
Cache-Control:缓存的控制
Transfer-Encoding:HTTP正文传输的编码方式
②请求首部字段
Host:请求资源的服务器
Accept:能被处理的媒体类型
Accept-Charset:能被接受的字符集
Accept-Encoding:能被接受的编码方式
Accept-Language:能被接受的自然语言
③响应首部字段
Accept-Ranges:可接受的字节范围
Server:HTTP服务器信息
Location:客户端重新定位的URL
④实体正文首部字段
Allow:资源可接受的HTTP方法
Content-Type:实体正文的类型
Content-Language:实体正文的自然语言
Content-Encoding:实体正文的编码方式
Content-Length:实体正文字节数
Content-Range:接受的字节范围,一般用于发送需要部分资源请求
HTTP的缺点有三个:
①使用明文不加密,可能会被窃取信息
②不对通信方进行验证身份,可能会遭受伪装
③不能保证发送的报文的完整性,可能会被篡改
将HTTP的缺点给改正,对正文使用SSL加密,验证通信方的身份以及保证了报文的完整性。
①利用均衡负载优化和加速HTTP应用
②利用HTTP Cache来优化网站
我发现还是先将主要需要学习的先完成,然后再来学习面经。我之后会更新关于框架类ssm的学习博客。