浏览器访问服务器时,都发生了什么?

来源:互联网 发布:规范查询软件 编辑:程序博客网 时间:2024/05/16 21:34

        前几天写了Servlet的转发(forward)和重定向(redirect),今天继续写一个相关的知识点,使用Servlet开发技术开发的后台服务中,浏览器访问服务器时发生了什么。(欢迎交流指正!)


        直入正题,简单来说,浏览器在访问服务器时,浏览器发送请求给服务器,服务器调用servlet,servlet根据请求调用相应业务逻辑处理,拿到结果并返回给服务器,服务器发送给浏览器。

        看起来非常简单,不过我们来详细分析一下:

        1.浏览器向服务器发送建立连接(ip:端口号)的请求(涉及三次握手)

        2.将请求数据打包发送给服务器

        3.服务器创建request和response对象,将请求包解析放入request中

        4.根据资源路径找到servlet配置,通过反射创建servlet实(若已创建则直接使用,servlet有请求到达的时候才会创建也可以在web.xml配置load-on-starup,容器加载时就创建,0为优先级最高。)

        5.调用Servlet的service( )方法,将request和response作为参数传递

        6.Servlet通过request获取参数,将处理结果放入response中

        7.服务器读取response信息

        8.服务器将结果打包发送给浏览器。

        9.发送完毕关闭连接。(涉及四次挥手)

        10.浏览器解析数据包,取出数据生成响应界面


        上面的过程中还涉及到三个知识点:TCP协议的三次握手(连接)和四次挥手(断开)、浏览器服务器互相发送的数据包、session与Cookie(下篇再讲)。

        首先讲一下数据包,由浏览器发送给服务器的,我们可以称之为请求数据包,服务器发送给浏览器的称之为响应数据包。那里面都有什么东西呢?

        请求数据包结构:

        1. 请求行:请求方式(get/post)、资源路径、协议类型与版本

        2. 若干消息头:如jsp的page指令中的,content-type= text/html等

        3. 实体内容:post的话请求参数放这里,get请求参数附在资源路径上

        响应数据包结构跟请求数据包差不多:

        1. 状态行:状态码(200,404,500...),协议类型与版本

        2. 若干消息头:(如我们上篇文章提到的重定向(redirect)原理:服务器向浏览器发送一个302状态码和一个消息头location,浏览器接收到后会立即向location指向的地址发送请求)

        3. 实体内容:处理结果


        扩展:(在《HTTP权威指南》一书中,对于URI的定义是:统一资源标识符;对于URL的定义是:统一资源定位符。二者的区别在于,URI表示请求服务器的路径(appname开始),定义这么一个资源。而URL同时说明要如何访问这个资源(http://))


        在讲TCP协议的三次握手和四次挥手之前,我们要先了解一下TCP报文的报头中的几个标志性字段:

        1、 SYN:同步连接序号,TCP SYN报文就是把这个标志设置为1,来请求建立连接;

        2、 ACK:请求/应答状态。0为请求,1为应答;

        3、 FIN:结束连线。如果FIN为0是结束连线请求,FIN为1表示结束连线;

        4、 RST:连线复位,首先断开连接,然后重建;

        5、 PSH:通知协议栈尽快把TCP数据提交给上层程序处理。


        三次握手首先Client端发送连接请求报文,Server器接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server器发生ACK报文,并分配资源,这样TCP连接就建立了。具体看图:

        

        1. 客户端-->服务器 连接请求:发送SYN=1请求报文

        2. 服务器-->客户端 授予连接:回复ACK=1应答报文,服务器分配资源

        3. 客户端-->服务器 确认连接:回复ACK=1应答报文,客户端分配资源

        三次握手,TCP连接建立。


        四次挥手:

        Client端发起中断连接请求,发送FIN报文。

        Server端接到FIN报文后发送ACK,告诉Client端请求收到了但数据未传输完成,Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。

        当Server端确定数据已发送完成,则向Client端发送FIN报文,告诉Client端数据发完准备关闭连接。

        Client端收到FIN报文后发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。

        Server端收到ACK后,断开连接。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,Client端也关闭连接。

        TCP连接关闭。

        

        客户端-->服务器 断开请求:发送FIN=1结束连线报文

        服务器-->客户端 应答请求:回复ACK=1应答报文,继续传输数据,客户端继续等待FIN

        服务器-->客户端 断开请求:发送FIN=1结束连线报文,收到客户端ACK=1报文后关闭

        客户端-->服务器 应答请求:回复ACK=1报文,客户端等待响应2MSL后无响应则关闭

        四次挥手,TCP连接关闭。


        其中还涉及到session和Cookie的相关知识,日后再补充。更加底层的事情目前还不了解,如有错漏,欢迎交流指正!

        PS:图片来源与网络,侵删~

1 0