当前位置: 首页 > news >正文

深入剖析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

相关文章:

  • Linq To Sql进阶系列 -目录导航
  • 美国少女模仿电影情节“蒙眼驾车” 或遭指控
  • LOJ #6485 LJJ 学二项式定理
  • python最赚钱的4个方向,你最心动的是哪个?
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 组复制官方翻译九、Group Replication Technical Details
  • Kafka在windows下的配置使用
  • IntelliJ IDEA 18 周岁
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 马上搞懂 GeoJSON
  • 阿里国际站新外贸系统上线 助中小企业“数字化出海”
  • 2019-1-21作业
  • bug集合js1--Unexpected token o in JSON at position 1
  • 为什么阿里巴巴不建议在for循环中使用+进行字符串拼接
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • Java 多线程编程之:notify 和 wait 用法
  • maya建模与骨骼动画快速实现人工鱼
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • vue脚手架vue-cli
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 第十八天-企业应用架构模式-基本模式
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 聊聊flink的BlobWriter
  • 扑朔迷离的属性和特性【彻底弄清】
  • 前端性能优化——回流与重绘
  • 设计模式 开闭原则
  • 使用parted解决大于2T的磁盘分区
  • 网络应用优化——时延与带宽
  • 延迟脚本的方式
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • #HarmonyOS:Web组件的使用
  • #微信小程序(布局、渲染层基础知识)
  • $.ajax,axios,fetch三种ajax请求的区别
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (C++17) optional的使用
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)3D模板阴影原理
  • (转载)Google Chrome调试JS
  • (轉貼) UML中文FAQ (OO) (UML)
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Core中的去虚
  • .NET NPOI导出Excel详解
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .Net程序帮助文档制作
  • @RequestMapping 的作用是什么?
  • [ C++ ] STL_list 使用及其模拟实现
  • [20170705]lsnrctl status LISTENER_SCAN1
  • [AIGC] Java 和 Kotlin 的区别
  • [android]-如何在向服务器发送request时附加已保存的cookie数据
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [Bada开发]初步入口函数介绍
  • [BZOJ1178][Apio2009]CONVENTION会议中心
  • [git] windows系统安装git教程和配置