深入剖析Tomcat(1)

之前几个月在忙着项目,期间也有在学习一些源码知识,主要包括spring ioc,java多线程(主要是AQS)和一些杂七杂八的东西。ioc和aqs给我的收获应该说是巨大的,我主要是通过spring 技术内幕跟着源码来学习spring ioc的,aqs主要是跟着一个博客学习,那个博客写的非常非常的好(https://blog.csdn.net/javazejian),有兴趣的朋友可以去看看,然后还有一些同事的帮助下,大概看懂了aqs的代码思路和主体设计。这两个经典的源码以后有时间还是要多看几次的,在工作学习的过程中,我又发现了自己对容器知识的极度欠缺,因此重新拿起了how tomcat works来学习,昨天弄个代码环境都弄了好久,可见自己的基础之差,其实这本书对代码讲得也非常详细,但是每一章的内容都是可以运行的,因此我觉得将每一章的内容写出来作为一个总结复习还是很有必要的。

 

第一章的代码是用socket来实现一个服务器,主要功能是可以在页面上请求一个url,然后再页面上返回一个html页面。还有一个小功能是请求一个/SHUTDOWN命令可以让http服务器停止。

这个功能的实现用了三个类来实现,HttpServer Request Response;

HttpServer作为主要的入口类,里面有主函数,在主函数里面模拟启动一个http服务。Request类封装了一个http请求;Response类封装了http响应。

先从入口说起吧,HttpServer里面的main函数先new了一个HttpServer的实例,然后就调用了HttpServer里面的await方法(因为wait方法是Object类的自带方法不允许重载)。

 

然后看await方法:这里就是新建了一个serverSocket类来启动一个服务器。

通过传入端口,ip地址和一个叫做backlog的参数就好了,这个参数的意思叫做在服务器拒绝接收传入的请求以前,传入的连接请求的最大队列长度。

 

接下来就是一个while循环,如果shundown标志位不为true就一直尝试通过serverSocket来accept socket。然后通过socket获得输入输出流。然后将输入流inputStream赋给一个Request类,然后在request类中需要将这个url的后面的http://localhost:8080/index.html后面的/index.html这部分解析出来。

parse的代码如下:

 

 将输入的字节流一个个地转换成char,然后写进StringBuffer中,最终的结果就是这样的:

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134
Accept-Language: zh-CN
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive

 我们看到我们想要的东西就是在一行的GET后面,然后这个例程就是通过/index.html前后的空格来parse出来的,然后会暂时保存在Request的内部成员变量中。

然后我们接着看主函数,然后也很简单,将request实例赋给response实例(将解析出来的url信息带给response),然后再将outputStream赋给response,再通过response来输出静态资源。

public void sendStaticResource() throws IOException {
byte[] bytes = new byte[BUFFER_SIZE];
FileInputStream fis = null;
try {
File file = new File(HttpServer.WEB_ROOT, request.getUri());
if (file.exists()) {
fis = new FileInputStream(file);
int ch = fis.read(bytes, 0, BUFFER_SIZE);
while (ch!=-1) {
output.write(bytes, 0, ch);
ch = fis.read(bytes, 0, BUFFER_SIZE);
}
}
else {
// file not found
String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: 23\r\n" +
"\r\n" +
"<h1>File Not Found</h1>";
output.write(errorMessage.getBytes());
}
}
catch (Exception e) {
// thrown if cannot instantiate a File object
System.out.println(e.toString() );
}
finally {
if (fis!=null)
fis.close();
}
}

主要就是这段代码了,主要工作就是找到index.html文件,然后将它用FileInputStream读进byte[]里面。然后通过outputStream的write方法写出去。(这里至于是怎么写到屏幕上的,暂时不太明白)。
然后就是关闭socket操作,关闭文件输入流等操作了,还有就是会判断/SHUTDOWN 来判断while循环是否继续。


 

转载于:https://www.cnblogs.com/kobebyrant/p/how_tomcat_works_1.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值