首先我们回顾下网络基础知识
网络基础
我们学习过网络工程的清楚,网络协议被分为七层或四层,我们常用的实现的最多的就是四层协议
网络接入层:为数据传输提供物理条件
网际互连层:寻找目标网络节点
传输层:传输数据(byte流)
应用层:数据的展现层,使用数据
TCP/IP一般会放在一起来说,但是他们是两个不同的协议,TCP应用在传输层上,而IP协议则应用在网络层,负责帮需要传输的数据虚招目的地址,而TCP则负责传输这些数据。我们需要知道的是TCP/IP它只是一个协议规范,并不是具体实现,具体的实现工作是需要交给我们自己的,在我们java web 这个协议的实现者就是socket。还有一个与TCP对立的协议是UDP,他们俩的区别就是前者是进行可靠传输,TCP在进行数据传输之前一般都会进行三次握手和四次挥手来完成通信规则,而UDP则是不可靠传输。
当传输层将数据传送出去之后,应用层就可以接收到这些数据,应用层通过HTTP协议就可以拿到这些数据,和前面一样,HTTP是一个协议,而在java web中servlet则是一个标准,servlet容器则是他的实现,,servle容器t负责对数据进行处理。然后响应客户端。常见的servlet容器有tomcat,jetty
使用socket完成一次数据通信
socket分为serversocket和socket,分别为服务和客户端,服务端监听某一个端口的请求。客户端则连接这个端口进行数据的传输。
服务端在 127.0.0.1 6666 地址上进行监听客户端的请求
public static void main(String[] args) throws Exception {
ServerSocket serverSocket=new ServerSocket(6666);
//阻塞监听
Socket accept = serverSocket.accept();
//从accept获取客户端发送过来的消息
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(accept.getInputStream()));
String line=bufferedReader.readLine();
System.out.println("服务端收到来自客户端的消息:"+line);
accept.close();
serverSocket.close();
}
客户端连接127.0.0.1 6666
public static void main(String[] args) throws Exception, IOException {
Socket socket=new Socket("127.0.0.1", 6666);
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter=new PrintWriter(outputStream);
printWriter.write("测试中文行不行");
printWriter.flush();
socket.close();
}
通过上面两端代码就可以完成一次通信。
动手实现http协议的思想
先来介绍下http协议
可以看出http协议对请求报文和响应报文都有一定的规范,网络在数据的传输过程中,必须遵循这种规范才可以进行传输,那么我们如何能实现一个简单的http协议呢,我们只需要在我们上面的例子进行改动就可以了,首先客户端在给服务端发送数据的时候,我们需要对我们的请求数据进行一个封装,格式如请求报文那样,服务端在收到客户端的请求,在得到数据流之后,需要进行一行一行进行解析,解析出方法名(POST,GET,DELETE),请求地址,协议名称,根据不同协议进行不同的处理,再到后面请求参数的解析,通过得到url,来调用不同的方法(这里也就是我们的servlet容器需要做的),在服务端处理好客户端传过来的数据之后,我们需要对客户端进行响应,这次我们将需要响应给客户端的消息封装成 响应报文那样,返回给客户端,客户端也同服务端那样将数据进行解析出来。这样一个简单的http协议就可以出来了。
tomcat的组成及运行过程
tomcat最顶层的容器叫做server,代表整个服务器,Server中可以包含多个service,默认tomcat中之配置了一个service,service又是由多个connector和一个container组成,connector负责用户请求的连接,container负责管理servlet和处理请求。
在tomcat的所有组件中都是通过实现lifecycle接口,实现整个生命周期的管理工作,tomcat的主函数实在Boostrap中main方法中。通过对bootstrap进行初始化,根据传给main函数的参数完成不同的命令操作。
container
在tomcat中service使用container和connector组成,其中container下有四个子容器,并且这些容器都继承了BaseContainer.四个自容器分别是Engine,Host,Context,Wrapper,他们是逐层包含的关系。作用如下
Engine:用来管理多个站点,一个service只有一个engine
Host:代表一个站点,通过配置host添加站点
Context:代表一个部署的应用
wrapper:对servlet进行封装
一个host下面可以配置多个context.也就是可以配置多个应用
Pipeline-Value管道
我们知道filterchain采用的是责任链模式,依次执行数据链中动作,Pipeline-Value管道也采用的是责任链默认,依次往下执行,通过getNext得到下一个Value,不过与普通的责任链模式不同的是Pipeline-Value管道 在每个责任链的末端对会有一个特殊的value,这个特殊的value用来做什么呢,他用来调用写一个容器的管道。每个容器都会有自己特定的value,StandardEngineValue,StandardHostValue,StandardContextValue,StandardWrapperValue,所以在整个流程中是这样进行调用的
Engine管道会依次执行自己的value,执行到最后一个StandardEngineValue,会触发执行host管道,host管道执行到StandardHostValue,会触发指定context的管道,执行到StandardContextValue,会调用wrapper,最后执行StandardWrapperValue
Connector
connector负责接受请求,并将请求封装成Request和Response来具体处理,底层使用socket来进行tcp/IP通信,监听用户请求,将请求数据封装成Request和Response按照http协议标准进行封装,然后交给Container,也就是servlet容器,servlet容器处理之后回相应connector,connector使用socket将相应数据返回给客户端,一次请求响应过程到此结束
既然connector即实现了tcp/ip协议又实现了http协议,那么到底是怎么完成的呢?
首先connect通过ProctocolHandler,不同的协议(http,https。。http1.1)有不同的实现。ProtocolHandler有三大组件,分别为Epoint,Processor,Adapter,其中Epoint则是进行底层socket网络连接,实现TCP/IP协议,Proocessor将Epoint接收到的socket数据封装成Request和Reponse,实现http协议,Adapter则是去请求contener,将res,rep适配到servlet中。由servlet来具体实现http协议中的数据处理。
总结
总结一下用户在浏览器中发起请求到tomcat进行处理,再到最后的响应的整个流程
①用户发起一个请求
②进行TCP连接,完成三次握手
③Epoint监听到客户端发来的请求,接受到socket
④processor负责将epoint接受到的socket按照http协议进行封装成request,response
⑤adapter将封装好的数据丢给最顶层的container(Engine)
⑥由Engine依次执行Pipeline-Value管道,期间通过请求地址的URL来去调用不同的下层容器
⑦一直到最后的StandardWrapperValue,其实这个代表的就是servlet了。
⑧接着会执行dofilter操作,如果有的话
⑨filter链执行完毕,最终到达我们编写的servlet
⑩servlet处理好之后,返回响应数据,原路返回
⑪iconnect收到响应后,Epoint则会将响应数据写到socket中,进行客户端的响应操作。
⑫执行四次挥手,断开连接。
⑬请求结束
欢迎关注我的微信公众号
乐哉码农
网友评论