深入剖析tomcat(一)--一个简单的web服务器
2016-06-05 00:12
549 查看
一个简单的web服务器
本系列博客为《深入Tomcat》一书的读书笔记,我也是从这本书开始接触Tomcathttp协议
socket
ServerSocket类
应用程序
http协议
http使用的是可靠的Tcp连接,默认使用Tcp80端口,总是由客户建立连接并发送http请求来初始化一个事物的。http请求
一个http请求包含以下三个部分:
请求方法——统一资源标识符(URI)——协议/版本
请求头
实体
在请求头和请求实体正文之间有一个空行,该空行只有CRLF符(回车换行符),这个空行对http请求格式非常重要
http响应
与http请求类似,http响应也包括三部分:
协议(如htttp/1.1)——状态码——描述
响应头
响应实体段
同样,响应头和响应实体正文之间由只包含CRLF的一个空行分隔。
socket类
创建一个简单的socket例子用于与本地http服务器通信,发送http请求,接受服务器的响应信息:package firstSection; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class SocketTest { public static void main(String [] args){ try { Socket socket=new Socket("127.0.0.1", 8080); OutputStream os=socket.getOutputStream(); PrintWriter out=new PrintWriter(os, true); BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream())); //send a http request out.println("GET /index.jsp HTTP/1.1"); out.println("Host: localhost:8080"); out.println("Connection:close"); out.println(); //read the response StringBuffer s=new StringBuffer(8096); boolean loop=true; while(loop){ if(reader.ready()){ int i=0; while(i!=-1){ i=reader.read(); s.append((char)i); } loop=false; } Thread.currentThread().sleep(50); } System.out.print(s.toString()); socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
注意防火墙可能会是程序失败
ServerSocket类
构造函数:new ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException//backlog表示服务器子啊拒绝接受传入的请求之前,传入请求的最大队列长度,backlog 参数必须是大于 0 的正值。如果传递的值等于或小于 0,则使用默认值
应用程序
该程序仅仅发送位于指定目录的的静态资源请求,如html文件和图片文件,他可以将接收的http请求字节流打印到控制台,但是并不能发送任何头信息到浏览器,如日期和cookies等HttpServer类:
package firstSection; 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; public class HttpServer { /** * web_root is the directory where our html and other files reside. * for this package web_root is the "web_root"directory under the working directory * the working directory is the location in the file system from where the java command was invoke */ 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){ HttpServer server=new HttpServer(); server.await(); } public void await(){ ServerSocket serverSocket=null; int port=8080; try { serverSocket=new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1")); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStac 4000 kTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } while(!shutdown){ Socket socket=null; InputStream in=null; OutputStream out =null; try { socket=serverSocket.accept(); in=socket.getInputStream(); out=socket.getOutputStream(); //parse request Request request=new Request(in); request.parse(); //create response obj Response response=new Response(out); response.setrequest(request); response.sendStaticResourse(); //close the soclet socket.close(); shutdown=request.geturi().equals(SHUTDOWN_COMMAND); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); continue; } } } }
Request类:
package firstSection; import java.io.IOException; import java.io.InputStream; public class Request { private InputStream in; private String uri; public Request(InputStream in){ this.in=in; } public void parse(){ StringBuffer req=new StringBuffer(2048); int i; byte[] buffer=new byte[2048]; try { i=in.read(buffer); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); i=-1; } for(int j=0;j<i;j++){ req.append((char)buffer[j]); } System.out.print(req.toString()); uri=parseUri(req.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 uri; } }
Response类:
package firstSection; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; public class Response { private Request request; private OutputStream out=null; public static final int BUFFER_SIZE=1024; public Response(OutputStream out){ this.out=out; } public void setrequest(Request request){ this.request=request; } public void sendStaticResourse()throws IOException{ FileInputStream fis=null; byte []bytes=new byte[BUFFER_SIZE]; try { File file=new File(HttpServer.WEB_ROOT,request.geturi()); if(file.exists()){ fis=new FileInputStream(file); int re=fis.read(bytes, 0, BUFFER_SIZE); while(re!=-1){ out.write(bytes, 0, re); re=fis.read(bytes, 0, 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>"; out.write(errorMessage.getBytes()); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally { if(fis!=null){ fis.close(); } } } }
相关文章推荐
- java-模拟tomcat服务器
- i-jetty环境搭配与编译
- 实现单Tomcat多Server配置
- 生产环境下的Tomcat配置
- Linux部署Tomcat服务器
- jenkins------结合maven将svn项目自动部署到tomcat下
- 如何搞定tomcat这只喵~
- tomcat在opensuse下开机自启失败的原因分析及解决方法
- jsp项目中更改tomcat的默认index.jsp访问路径的方法
- Tomcat 多端口 多应用
- tomcat 5.0 + apache 2.0 完全安装步骤详解
- Tomcat安全设置 win2003 下tomcat权限限制
- Jsp和PHP共用80端口整合Apache和Tomcat(访问时无需加端口号)
- Tomcat服务器 安全设置第1/3页
- tomcat 6.0.20在一个机器上安装多个服务的方法
- Tomcat 5.5 数据库连接池配置
- Tomcat内存溢出分析及解决方法
- apache tomcat 一个网站多域名的实现方法
- Tomcat无法加载css和js等静态资源文件的解决思路