一次URL请求过程--tomcat

一:请求的过程

1.DNS域名解析

2.建立TCP连接(三次握手)

3.发送请求--tomcat进行处理

4.四次挥手关闭连接 

二:详解1---DNS域名解析

     1、浏览器会检查缓存中有没有这个域名对应的解析过的IP地址,如果有,这个解析过程就结束。

     2、缓存中没有数据,浏览器会查找操作系统缓存中是否有这个域名对应的DNS解析结果。

     3、前两个无法解析时,就要用到本地区的域名服务器。它们一般都会缓存域名解析结果。大约80%的域名解析到这里就结束了,所以LDNS主要承担了域名的解析工作。

     4、如果LDNS仍然没有,就直接到Root Server域名服务器请求解析。

     5、根域名服务器返回给本地域名服务器一个所查询的主域名服务器(gTLD Server)地址。

     6、本地域名服务器LDNS再向上一步返回的gTLD服务器发送请求。

     7、主域名服务器查找并返回此域名对应的Name Server域名服务器的地址,这个Name Server通常就是用户注册的域名服务器。

     8、域名服务器会查询存储的域名和IP的映射关系表,在正常情况下都根据域名得到目标IP地址,连同一个TTL值返回给LDNS Server域名服务器。

     9、返回该域名对应的IP和TTL值,LDNS会缓存这个域名和IP的对应关系,缓存时间由TTL值控制。

     10、把解析的结果返回给用户,用户根据TTL值缓存在本地系统缓存中,域名解析过程结束。

 

三:详解2---建立TCP连接

 建立TCP连接需要三次握手:建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:

(1)第一次握手:
Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:
Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:
Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

问题1:SYN攻击

SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了。

使用如下命令可以让之现行:netstat -nap | grep SYN_RECV

问题2:为什么是三次握手

(a)若两次握手,客户端收到服务端的应答后进入ESTABLISHED(已建立连接状态),而服务端在收到客户端的连接请求之后就进入了ESTABLISHED状态。如果出现网络拥塞,客户端发送的连接请求报文A过了很久没有到达服务端,会超时重发请求报文B,服务端正确接受并确认应答,连接建立并开始通信传输数据,等通信结束之后释放连接。此时,如果之前失效的连接请求A到达服务端,由于两次握手就能成功建立连接,服务端收到请求A之后进入ESTABLISHED已建立连接状态,等待发送数据或者主动发送数据,此时,客户端已经进入CLISED断开连接状态,服务器会一直等下去,浪费服务器连接资源。

(b)建立连接需要四次握手

         由于三次握手已经能确保建立可靠的连接,所以不需要四次或更多的握手。

第三次握手主要是为了防止已失效的请求报文段突然又传送到了服务端而产生连接的误判 

换种表述:为什么要三次握手?不是一次,两次或者四次。

我们来论证一下,如果只有一次会发生什么情况,a向b发起连接请求,假设b没收到,则b其实完全不知道a发起了请求,而a也完全不知道b收没收到,所以一次握手是不可靠的;如果两次握手呢,a向b发起连接请求,b收到a的请求给a回复一个请求,假设此时a收到了b的回复,a知道了b已经ready了,可b完全不知道a是否ready,有可能a并没有收到b的请求,也有可能收到了,但这些b都完全不知道,所以只是单向的建立了连接;如果是四次握手呢,其实第2次让a知道b ready了,第三次让b知道a也ready了,第四次完全就是多余了,会浪费网络资源。

 问题3:第三次握手失败时发生什么?

当第三次握手失败时的处理操作,可以看出当失败时服务器并不会重传ack报文,而是直接发送RTS报文段,进入CLOSED状态。这样做的目的是为了防止SYN洪泛攻击。

 四:详解3---tomcat请求处理

     1. 请求被发送到8080端口,被在那里侦听的Coyote HTTP/1.1 Connector获得 。

     2. Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应 。

     3. Engine获得请求,匹配它所拥有的所有虚拟主机Host (默认是localhost)

     4. localhost Host获得请求,匹配它所拥有的所有Context

     5. Context获得请求,在它的映射表中寻找对应的servlet

     6. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法

     7. Context把执行完了之后的HttpServletResponse对象返回给Host

     8. Host把HttpServletResponse对象返回给Engine

     9. Engine把HttpServletResponse对象返回给Connector

     10.Connector把HttpServletResponse对象返回给客户browser

五:详解四-----四次挥手

第一次挥手:TCP发送一个FIN(结束),用来关闭客户到服务端的连接。

第二次挥手:服务端收到这个FIN,他发回一个ACK(确认),确认收到序号为收到序号+1,和SYN一样,一个FIN将占用一个序号。

第三次挥手:服务端发送一个FIN(结束)到客户端,服务端关闭客户端的连接。

第四次挥手:客户端发送ACK(确认)报文确认,并将确认的序号+1,这样关闭完成。

问题1:那么为什么是4次挥手呢? 

      实际上两边连接完全可以分开看,用2次挥手断开其中一边连接,用另外2次挥手断开另一边的连接,最终完成整个连接关闭。之所以这样设计,是因为有可能某一边数据还未传输完,连接还未关闭。因为TCP被设计为全双工协议,可以任何一边单向发送数据。

问题2:   tcp握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢.

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

问题3: 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

第一,为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。
第二,A在发送完ACK报文段后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。

猜你喜欢

转载自www.cnblogs.com/ntbww93/p/9639921.html