锁定老帖子 主题:tomcat解析之简单web服务器(图)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (10) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-02-04
最后修改:2010-02-08
之前有javaeyer推荐了一本书《how tomcat works》,今天晚上看了看,确实不错,第一眼就着迷了。 于是乎就学着书上的例子敲了敲,学会了一个简单web服务器的大概实现,当然,这个简直就无法称之为web服务器,但是也算是走进web服务器的第一步吧。 这篇文章仅限于学习记录,文笔凌乱之处,还望各位见谅。 OK,下面进入正题; 开始之前,首先我们要清楚以下几个内容。
首先,一个最简单服务器包括三个部分:
这个服务器如何使用:
OK, 放上代码, 代码只有3个类,都挺简单的, 这个应用只是一个最最简单的雏形:
主类: HttpServer
package chapter1.simplewebserver; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.ServerSocket; import java.net.Socket; /** * * 下午11:59:29 * @author gogole_09 * 简单web服务器 */ public class HttpServer { //定位到webroot目录 public static final String WEB_ROOT=System.getProperty("user.dir")+File.separator+"webroot"; //停止命令 private static final String SHUTDOWN_COMMAND="/SHUTDOWN"; //是否接收到了关闭命令 private boolean shutdown=false; /** * 等待命令 */ public void await(){ ServerSocket serverSocket=null; int port=8090; try { serverSocket=new ServerSocket(port,1,InetAddress.getByName("127.0.0.1")); } catch (Exception e) { e.printStackTrace(); System.exit(1); } //监听端口,等待请求。 while(!shutdown){ Socket socket=null; InputStream input=null; OutputStream output=null; try { socket=serverSocket.accept(); //输入流 有过jsp编程的哥们都知道这是干嘛的 input=socket.getInputStream(); //输出流 output=socket.getOutputStream(); //构建请求 Request request=new Request(input); //解析请求信息 request.parse(); //响应类 Response response=new Response(output); response.setRequest(request); response.sendStaticResource(); //处理完毕,关闭 socket.close(); //检查提供的URI是否为shutdown命令 shutdown=request.getUri().equals(SHUTDOWN_COMMAND); } catch (Exception e) { e.printStackTrace(); continue; } } } public static void main(String[] args) { HttpServer server=new HttpServer(); server.await(); } }
接下来是请求类: Request
package chapter1.simplewebserver; import java.io.IOException; import java.io.InputStream; /** * * 上午12:09:36 * @author gogole_09 * 简单服务器的请求类 */ public class Request { private InputStream input; private String uri; public Request(InputStream in) { this.input=in; } /** * 解析Uri操作 */ public void parse() { StringBuffer buf=new StringBuffer(); int i; byte[] buffer=new byte[2048]; try { i=input.read(buffer); } catch (IOException e) { e.printStackTrace(); i=-1; } for(int j=0;j<i;j++){ buf.append((char)buffer[j]); } System.out.println(buf.toString()); uri=parseUri(buf.toString()); } /** * 解析Uri * 为什么要以' '为做标识 , 这里需要了解HTTP协议的相关结构; * 一个请求行 以 请求方法开头 + 请求URI+ 请求协议版本 + CRLF字符结束 * 比如,你请求index.html 用GET方式 ,那么Uri形式为: * * GET /index.html HTTP/1.1 * * * @param requestString * @return */ 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; } }
有了请求了,服务器就得响应啊,试想,我发个请求没反应,你的第一反应是不是想砸电脑呢? OK,Response类来了。
package chapter1.simplewebserver; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; /** * * 上午12:10:58 * * @author gogole_09 简易服务器的响应类 */ public class Response { /** * HTTP响应格式:= Status-Line * *((general-header|response-header|entity-header)CRLF) CRLF [message-body] * Status-Line=HTTP-Version SP(空格) Status-Code SP Reason-Phrase CRLF * */ private static final int BUFFER_SIZE = 1024; Request request; private OutputStream output; public Response(OutputStream output) { this.output = output; } public void setRequest(Request request) { this.request = request; } /** * 服务器解析并发送静态资源 * @throws IOException */ 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 { //文件没找到 String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type:text/html\r\n" + "Content-Length:23\r\n"+"\r\n<ht>File Not Found</h1>"; output.write(errorMessage.getBytes()); } } catch (Exception e) { System.out.println(e.toString()); }finally{ if(fis!=null) fis.close(); } } }
OK,现在这个应用可以运行了,但是你运行起来,没办法用,为什么, 因为还需要有用户请求的静态资源。 在HttpServer类中,我们hard code了一个webroot目录,约定把所有的静态资源都放到这个目录下面的。 下面我们就把这个目录建好,并放一点资源进去 ,我是这样放的, 如图:
index.html 中 就只有一行代码:
OK, 下面我们运行一下 HttpServer ,得到页面 如下图: 在控制台,你将会看到程序打印出:
接着,我们尝试请求一个不存在的资源: 我们会的到一个404的错误页面. OK, 一个简单的web服务器就完成了, 虽然简单,但是我们可以通过这个了解一个大概的流程。 以及复习一下java net包与HTTP/1.1协议的一些知识。
也希望这个篇文章对都有需要的人有帮助。
PS: 最近有很多朋友都问这本书哪里有买,我本人并非看的纸质的,而是电子版的, 需要下载的可以去新浪共享频道找找, 我的是从哪里下来的, 中文书名就叫 <tomcat工作原理> 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-02-06
请问楼主浏览器上装的什么东东,看请求资源的那个?
|
|
返回顶楼 | |
发表时间:2010-02-06
曾经de迷茫 写道 请问楼主浏览器上装的什么东东,看请求资源的那个? 是Http Watch. 查看请求url,传递的参数,以及服务器返回数据的好东西。 |
|
返回顶楼 | |
发表时间:2010-02-07
应该是how tomcat works
|
|
返回顶楼 | |
发表时间:2010-02-07
how tomcat works在中国买不到,这么好的书。
|
|
返回顶楼 | |
发表时间:2010-02-08
wanggp 写道 应该是how tomcat works 嘿嘿,是的。 书名写错了,马上修正。 |
|
返回顶楼 | |
发表时间:2010-02-16
为何不用 NIO 来实现呢,,
|
|
返回顶楼 | |
发表时间:2010-02-18
也没你说得那么好,一般般吧,有些东西说得太罗嗦.
|
|
返回顶楼 | |
发表时间:2010-03-22
Tomcat 不也是处理Socket吗?
|
|
返回顶楼 | |
发表时间:2010-03-22
最后修改:2010-03-22
比较精华的地方是启动、关闭操作。。
占用一个port监听关闭命令,呵呵。 这里可以对java项目的友好关闭做一下处理 |
|
返回顶楼 | |