tomcat解析之简单web服务器(图)
链接地址:http://gogole.iteye.com/blog/587163
之前有javaeyer推荐了一本书《how tomcat works》,今天晚上看了看,确实不错,第一眼就着迷了。 于是乎就学着书上的例子敲了敲,学会了一个简单web服务器的大概实现,当然,这个简直就无法称之为web服务器,但是也算是走进web服务器的第一步吧。
这篇文章仅限于学习记录,文笔凌乱之处,还望各位见谅。 OK,下面进入正题;
开始之前,首先我们要清楚以下几个内容。
首先,一个最简单服务器包括三个部分:
web服务器----HttpServer
请求---Request
响应---Response
这个服务器如何使用:
1. 请求静态资源 通过 http://localhost:8090/index.html
成功 则返回页面, 否则会返回 File Not Found 的错误信息.
PS:比如上面的index.html 必须放在一个webroot目录下.
2. 服务器的关闭通过uri来处理
通过http://lcoalhost:8090/SHUTDOWN 这个Uri来停止服务器.
需要注意的其他几个知识点:
1. HTTP/1.1 协议的知识。 比如 请求,响应的结构。 发送与接收形式等.
2. Java中网络的相关只是 ServerSocket 与 Socket 的使用.
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工作原理>

评论
现在的场景是我用sh脚本nohup启动一个java进程后台运行,然后怎么友好关闭这个线程呢? 最简单的就是向一个端口发stop请求。
占用一个port监听关闭命令,呵呵。 这里可以对java项目的友好关闭做一下处理
这个port监听不止是单独处理关闭,所有的请求都通过端口的,只是为了简单,根据URI来确定是否关闭。 实际在tomcat内部,还用到了ShutDownHook这个东西来处理 tomcat的关闭。 有兴趣的可以看看how tomcat works的ShutDownHook这个章节。 呵呵, 欢迎交流。
占用一个port监听关闭命令,呵呵。 这里可以对java项目的友好关闭做一下处理
这个port监听不止是单独处理关闭,所有的请求都通过端口的,只是为了简单,根据URI来确定是否关闭。 实际在tomcat内部,还用到了ShutDownHook这个东西来处理 tomcat的关闭。 有兴趣的可以看看how tomcat works的ShutDownHook这个章节。 呵呵, 欢迎交流。
tomcat内部也是处理socket的, 不知有什么不对吗?
占用一个port监听关闭命令,呵呵。 这里可以对java项目的友好关闭做一下处理
嘿嘿,是的。 书名写错了,马上修正。
是Http Watch. 查看请求url,传递的参数,以及服务器返回数据的好东西。
tomcat解析之简单web服务器(图)的更多相关文章
- C#中使用Socket实现简单Web服务器
上一篇博客中介绍了怎样使用socket访问web服务器.关键有两个: 熟悉Socket编程: 熟悉HTTP协议. 上一篇主要是通过socket来模拟浏览器向(任何)Web服务器发送(HTTP)请求,重 ...
- Socket网络编程--简单Web服务器(1)
这一次的Socket系列准备讲Web服务器.就是编写一个简单的Web服务器,具体怎么做呢?我也不是很清楚流程,所以我找来了一个开源的小的Web服务器--tinyhttpd.这个服务器才500多行的代码 ...
- 我叫Tomcat:一款web服务器
我叫Tomcat:一款web服务器 如何将我们的 Java 代码,运行在网络上,初学时,首先接触到的一般都是Servlet以及Jsp(或略过Jsp)而 Tomcat 就是这两者的容器,帮你处理动态网页 ...
- Socket网络编程--简单Web服务器(6)
本来是想实现ssl连接的,但是弄了好久都不成功,就索性不做了,等以后有能力再做了.所以这一小节就是本次的最后一节了.就简单的说几个注意点. 1.加个配置文件 使用单例模式,使用一个类,该类保存一些信息 ...
- Java 18 新特性:简单Web服务器 jwebserver
在今年3月下旬的时候,Java版本已经更新到了18.接下来DD计划持续做一个系列,主要更新从Java 9开始的各种更新内容,但我不全部都介绍,主要挑一些有意思的内容,以文章和视频的方式来给大家介绍和学 ...
- 理解与模拟一个简单web服务器
先简单说下几个概念,根据自己的理解,不正确请见谅. web服务器 首先要知道什么是web服务器,简单说web服务器就是可以使用HTTP传输协议与客户端进行通信的服务器.最初的web服务器只能用来处理静 ...
- java实现简单web服务器(分析+源代码)
在日常的开发中,我们用过很多开源的web服务器,例如tomcat.apache等等.现在我们自己实现一个简单的web服务器,基本的功能就是用户点击要访问的资源,服务器将资源发送到客户端的浏览器.为了简 ...
- Socket网络编程--简单Web服务器(4)
上一小节已经实现了对图片的传输,接下来就是判断文件是否为js,css,png等格式.我们增加一个函数用于判断格式 int WebServer::get_filetype(char *type,char ...
- Socket网络编程--简单Web服务器(5)
这一小节我们将实现服务器对get和post的请求进行对cgi程序的调用.对于web服务器以前的章节已经实现了对get和post请求的调用接口,接下来给出对应接口的实现. int WebServer:: ...
随机推荐
- Win7下安装Apache+PHP+MySQL
Win 7 下搭建 WAMP 环境本文安装方法适用于 Windows7 下的 Apache + MySQL + PHP(WAMP)安装,同时也适用于 Windows XP 系统下的安装和配置.一.安装 ...
- 实时消息传输协议 RTMP(Real Time Messaging Protocol)
实时消息传输协议(RTMP)最初是由 Macromedia 为互联网上 Flash player 和服务器之间传输音频.视频以及数据流而开发的一个私有协议.Adobe 收购 Macromedia 购以 ...
- GC算法之串行并行并发
串行收集器: 用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高.但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器.当然,此收集器也可以用在小数据量(100M左右)情况下的多 ...
- 关于 free() 函数用法的若干疑问
<C语言参考手册>中关于 free() 函数有如下描述. (1)free() 函数的原型 void free(void *ptr); (2)free 函数对以前由 malloc.callo ...
- Spring RESTful服务接收和返回JSON最佳实践
http://blog.csdn.net/prince_hua/article/details/12103501
- 射频识别技术漫谈(23)——ISO15693的载波、调制与编码
射频识别技术中的通讯大多是主从式,主动方一般是读写器,被动方称为“卡片”或“标签”.到底是叫“卡片”还是“标签”,好像也没有严格的区分.习惯上可以从以下4个方面界定:一是形状,卡片通常体积较大,更像“ ...
- c++builder 重载WindowProc、WndProc 截获消息(比Delphi多一个Message Map方法)
c++builder 重载WindowProc.WndProc 截获消息 方法一WindowProc void __fastcall myWindowProc(Messages::TMessage ...
- PHP查看在线服务器与本地服务器支持函数差别
在本地开发好的程序.代码,当传到服务器后,经常会出现罢工的事情.这时候就要考虑开发环境和在线的环境是否完全一致了.这里所说的一致性,包括了容器的配置.php的配置等等.下面所要解决的只是其中一项,你的 ...
- [cocos2dx笔记011]使用Cocostudio UI编辑器
本文地址:http://www.cppblog.com/zdhsoft/archive/2014/07/19/207715.html 笔记汇总:http://www.cppblog.com/zdhso ...
- 远程登录 Windows server 2008 黑屏
scenerio: 远程登录 Windows server 2008 黑屏,别人那里一切正常. Solution:在黑屏界面,点击桌面,按住Ctrl+Alt+End键 -> Log Off. ...