您的位置:首页 > 运维架构 > Tomcat

深入剖析tomcat(一)--一个简单的web服务器

2016-06-05 00:12 549 查看

一个简单的web服务器

本系列博客为《深入Tomcat》一书的读书笔记,我也是从这本书开始接触Tomcat

http协议

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();
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tomcat