tomcat源码编写计划连载(1)
2016-07-04 10:21
471 查看
以前没实在的接触过tomcat这个东西,对于应用服务器和服务器的概念也一直都很模糊,于是我决定抽时间出来去实现以下tomcat源码.tomcat的流程网上一堆,大家自己去熟悉一下就行了,我直接先实现一个简单的java http服务器。这样大家可以熟悉一下服务器的最基本的工作原理,当然也是tomcat的最基本的工作原理,tomcat原比这个复杂多了,后期会进行更新代码一共包含四个类,Client(发起请求) Server(接收请求) Request(类似于Servlet的Request Response ,类似于Servlet的Response),tomcat的处理流程是1.Server接收到Client发送的请求,交给Request解析HTTP请求,然后把Request和Response对象交给你写的Service处理。1.Client发送请求代码
import java.io.*; import java.net.InetAddress; import java.net.Socket; /** * Created by user1013 on 2016/7/1. */ public class Client { public static void main(String[] args){ try { Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 8080); OutputStream os = socket.getOutputStream(); //获取输入流 boolean autoflush = false; //socket的缓冲区 PrintWriter out = new PrintWriter(socket.getOutputStream(), autoflush); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //发送一个HTTP请求到web服务器 out.println("GET /index.jsp HTTP/1.1"); out.println("Host: localhost:8080"); out.println("Connection: Close"); out.println(); out.flush(); //同步获取服务器返回的信息,最长接收8096个字节的东西 boolean loop = true; StringBuffer sb = new StringBuffer(8096); while(loop){ System.out.println("準備讀取返回"); if(in.ready()){ int i = 0; while(i != -1){ i = in.read(); sb.append((char)i); } loop = false; } Thread.currentThread().sleep(500); } System.out.println(sb.toString()); socket.close(); } catch (IOException e) { e.printStackTrace(); System.out.println(e.getMessage()); } catch (InterruptedException e) { e.printStackTrace(); System.out.println(e.getMessage()); } } }2.Server接收请求代码
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; /** * Created by user1013 on 2016/7/1. */ public class Server { public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webRoot"; public static final String SHUTDOWN_COMMAND = "/SHUTDOWN"; private boolean shutdown = false; public static void main(String[] args) throws IOException { Server server = new Server(); server.await(); } // private void await() { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8080, 1, InetAddress.getByName("127.0.0.1")); } catch (IOException e) { e.printStackTrace(); } while( !this.shutdown){ try { System.out.print("等待接收消息。。。。"); Socket socket = null; InputStream input = null; OutputStream output = null; socket = serverSocket.accept(); input = socket.getInputStream(); output = socket.getOutputStream(); //1.解析请求 ,注意这两步的初始化Request和Response对象 Request request = new Request(input); request.parse(); //2.发送信息回去 Response response = new Response(output); response.setRequset(request); response.SendStaticResource(); //发送静态文件资源 socket.close(); this.shutdown = request.getUri().equals(Server.SHUTDOWN_COMMAND); } catch (IOException e) { e.printStackTrace(); continue; } } } }
3.Request 解析处理请求
import java.io.IOException;import java.io.InputStream;/*** Created by user1013 on 2016/7/1.*/public class Request {private InputStream input = null ;private String uri ;public Request(InputStream input){this.input = input;}public void parse(){StringBuffer request = new StringBuffer(2048);int i;byte[] buffer = new byte[2048];try {i = this.input.read(buffer);} catch (IOException e) {e.printStackTrace();i = -1;}for (int j = 0; j < i; j++) {request.append((char) buffer[j]);}System.out.print(request.toString());uri = this.parseUri(request.toString());}private String parseUri(String requestString){int index1, index2;index1 = requestString.indexOf(' ');if(index1 != -1){index2 = requestString.indexOf(' ',index1 + 1);if(index2 > index1){return requestString.substring(index1+1, index2);}}return null;}public String getUri(){return this.uri;}}
4.Response返回信息
import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;/*** Created by user1013 on 2016/7/1.*/public class Response {private static final int BUFFER_SIZE = 1024;private OutputStream output;private Request requset;public Response(OutputStream output){this.output = output;}public void SendStaticResource() throws IOException {byte[] bytes = new byte[Response.BUFFER_SIZE];FileInputStream fin = null;File file = new File(Server.WEB_ROOT, requset.getUri());if(file.exists()){fin = new FileInputStream(file);int ch = fin.read(bytes, 0, Response.BUFFER_SIZE);while(ch != -1){this.output.write(bytes);ch = fin.read(bytes, 0, Response.BUFFER_SIZE);}}else{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>";try {this.output.write(errorMessage.getBytes());} catch (IOException e) {} finally {if (fin!=null)fin.close();}}}public void setRequset(Request requset) {this.requset = requset;}}
上面这段代码是处理一个HTTP请求并返回一个静态资源的信息,你可以认为这个tomcat最最基本的实现。以上代码如果不懂Socket的自行学习一下,Socket可以关联很多东西.
个人感觉是比较重要的基础知识吧,其实它的本质只是一个TCP UDP操作的封装集合而已。可以牵扯到一些RPC之类的东西,反正网络之前的进程通信都是用这个。
相关文章推荐
- Nginx+Tomcat7+Mencached负载均衡集群部署笔记
- 解决8080端口被占用问题
- Linux学习(5)之安装Tomcat
- jenkins搭建自动化部署平台(svn+tomcat重启)
- Tomcat部署Web应用方法总结
- solr4.8单机部署(solr4.8+tomcat7)
- Tomcat源码分析之ClassLoader部分的设计详细分析
- tomcat+mysql绿色安装版本注意事项
- 阿里云服务器Linux CentOS安装配置(四)yum安装tomcat
- Jetty和tomcat的对比
- nginx多tomcat负载均衡
- 探索《How Tomcat Works》 心得(六) 加载器 上
- 【JavaWeb学习】之Tomcat配置
- eclipse - tomcat 远程调试
- An internal error occurred during: "Launching on Tomcat 7.x"
- 使用JVisualVM 远程监控Tomcat程序中使用JMX鉴权访问
- Tomcat学习-4
- tomcat目录结构
- Eclipse 的server窗口不能添加tomcat6.0/7.0/8.0等版本的解决方法
- 如何使用JVisualVM远程监控和优化Tomcat和Java程序的内存和CPU