在了解tomcat的基本原理之前,首先要了解tomcatt最基本的运行原理。

1.如何启动?

main方法是程序的入口,tomcat也不例外,查看tomcat源码,发现main是在Bootstrap 类中的;

2.如何建立连接?

要通讯,必须要建议socket连接,我们需要使用哪种socket,是根据它使用的哪种协议进行判断的。tcp协议or udp协议?http协议本身属于tcp协议,因此我们选择的socket是基本tcp协议的socket。在tomcat中,StandardServer 中 await() 方法具体实现了 socket连接;

3.使用哪种io模式?

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高;
  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器;
  • AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器
  • tomcat 使用了aio,bio、nio三种io模式,它们不同的应用各自发挥其优点。这里通过bio简单实现一个tomcat服务。

代码示例:

package com.io;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel; public class ChannelSocketTest {
public void start() throws IOException { // 1.新建NIO通道
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false); // 设置为非阻塞状态
ServerSocket socket = ssc.socket();
System.out.println("启动web服务");
socket.bind(new InetSocketAddress(8888)); while (true) {
SocketChannel channel = ssc.accept();
       if (channel!=null)
Thread thread = new Thread(new HttpServerThread(channel));
thread.start();
}
}
} // 内部类
private class HttpServerThread implements Runnable {
SocketChannel channel; HttpServerThread(SocketChannel channel) {
this.channel = channel;
} @Override
public void run() {
if (channel != null) { try {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
InetSocketAddress remoteAddress = (InetSocketAddress) channel.getRemoteAddress();
// System.out.println(remoteAddress.getAddress());
// System.out.println(remoteAddress.getPort());
channel.read(byteBuffer);
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
char c = (char) byteBuffer.get();
System.out.print(c);
}
// 此处打印执行的线程名称,永远为 main 线程
System.out.println(Thread.currentThread().getName() + "开始向web返回消息。。。");
ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024);
// 给客户端一个响应,即向输出流写入信息
String reply = "HTTP/1.1\n"; // 必须添加的响应头
reply += "Content-type:text/html\n\n"; // 必须添加的响应头
reply += "服务器返回的消息";
byteBuffer2.put(new String(reply).getBytes());
byteBuffer2.flip();
channel.write(byteBuffer2);
channel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} } public static void main(String[] args) throws IOException {
new ChannelSocketTest().start();
} }

在浏览器上输入:http://localhost:8888/

控制台输出:

第0行信息:Host: localhost:
第1行信息:Connection: keep-alive
第2行信息:Cache-Control: max-age=
第3行信息:User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
第4行信息:Upgrade-Insecure-Requests:
第6行信息:Accept-Encoding: gzip, deflate, br
第5行信息:Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
第8行信息:Cookie: JSESSIONID=F373E4FD1D4E6E57AB618563B796B909;
第7行信息:Accept-Language: zh-CN,zh;q=0.9
第9行信息:

注意:控制台上的输出包含http请求头信息,socket接收的流格式为字符类型,每一行都代表一种类型的信息,因此解析时需要逐行解析。之前使用BufferedReader的readLine( )方法,但是此方法是阻塞线程的,如果读取不到,会一直处理等待状态,因此配合ready( )方法一起使用。

上面代码在浏览器请求时,后台会执行两次,我们可以打开浏览器F12调试模式查看

发现有一个http请求,还有一个favicon.ico 图片(浏览器窗口图标)的请求。

java实现一个最简单的tomcat服务的更多相关文章

  1. 利用SpringCloud搭建一个最简单的微服务框架

    http://blog.csdn.net/caicongyang/article/details/52974406 1.微服务 微服务主要包含服务注册,服务发现,服务路由,服务配置,服务熔断,服务降级 ...

  2. java(itext) 一个很简单的PDF表格生成工具

    先上个效果图 因为做的项目涉及到数据预测,其中有大量打印业务来支撑实体店的运营,因为注重的是数据,要求简洁,清晰,所以写了个很简单也很实用的工具类. 如果需要编写样式或者插入背景,都可以查阅itex官 ...

  3. 动手实现一个较为简单的MQTT服务端和客户端

    项目地址:https://github.com/hnlyf168/DotNet.Framework 昨天晚上大致测试了下 ,490个客户端(一个收一个发)  平均估计每个每秒60个包  使用mqtt协 ...

  4. 一个非常简单的RPC服务

    1.servicefunctions.php <?php class ServiceFunctions { public static function getDisplayName($f,$l ...

  5. 使用Axis2创建一个简单的WebService服务

    使用过Java进行过WebService开发都会听过或者接触过Apache Axis2,Axis2框架是应用最广泛的WebService框架之一了. 这里使用Axis2来开发和部署一个最简单的WebS ...

  6. 自己模拟的一个简单的tomcat

    servlet容器的职责 总的来说,一个全功能的servlet容器会为servlet的每个HTTP请求做下面的一些工作: 1,当第一次调用servlet的时候,加载该servlet类并调用servle ...

  7. Tomcat 服务应用

    转自:http://wiki.jikexueyuan.com/project/tomcat/windows-service.html Tomcat8 是一个服务应用,能使 Tomcat 8 以 Win ...

  8. 简单ESB的服务架构

    简单ESB的服务架构 这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1. ...

  9. 新项目架构从零开始(三)------基于简单ESB的服务架构

    这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1.Common 在Com ...

随机推荐

  1. Spark- JdbcRDD以及注意事项

    先上Demo package com.rz.spark.base import java.sql.DriverManager import org.apache.spark.rdd.JdbcRDD i ...

  2. tensorflow笔记:模型的保存与训练过程可视化

    tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) tensorflow笔记:多层CNN代码分析 (三) tensorflow笔记:多层LSTM代码分析 ...

  3. 真相大白:为什么Entity Framework不能进行跨数据库查询(附解决方法)

    在上篇随笔中,我们发现Entity Framework在构建SQL语句时,将ToTable("CNBlogsTex.dbo.blog_PostBody")中的"CNBlo ...

  4. 公共域名服务DNS 114.114.114.114和8.8.8.8

    一.两者的联系 114.114.114.114和8.8.8.8,这两个IP地址都属于公共域名解析服务DNS其中的一部分,而且由于不是用于商业用途的,这两个DNS都很纯净,不用担心因ISP运营商导致的D ...

  5. Java 子类实例化对象的过程

    子类实例化是否会实例化父类? 不会.父类在子类实例化过程中是并没有被实例化,java中new子类没有实例化父类,只是调用父类的构造方法初始化了,子类从父类继承来的属性,这个调用是子类的对象调用的父类的 ...

  6. 有云Ceph课堂:使用CivetWeb快速搭建RGW

    转自:https://www.ustack.com/blog/civetweb/ 优秀的开源项目正在改变传统IT,OpenStack名头最响,已经成为了IaaS的事实标准.Ceph同样颇有建树,通过其 ...

  7. WEB-INFO里面的jsp文件不能通过href 访问,而只能通过 servlet访问

    href="<%=basePath %>index.jsp"> 这种确实 可以在jsp页面跳转至另一个页面,只不过要放在WEB-INFO外面,也就是项目根目录下面 ...

  8. JavaScript能做的事 是不是jQuery都能做>?

    比如修改表单中的action 并实现跳转  问题是此时没有点击表单中的submit 提交按钮?

  9. JQuery动态隐藏和显示DIV

    <head> <script language="javascript"> function HideWeekMonth() { $("#tt1& ...

  10. [ASP.NET] 修改web站点的默认编程语言

    当你点右键新建web窗体或者新建类的时候,默认编程语言是什么?有时候是C#,有时候是VB. 你找遍了所有配置,从web.config到iis express配置到sln文件,硬是没找到vs如何决定编程 ...