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:: ...
随机推荐
- hdu1114小猪抢劫银行
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1114 完全背包 题意:给出小猪钱罐的重量和装满钱后的重量,然后是几组数据,每组数据包括每种钱币的价值与重量 ...
- 0520 python
配置python环境变量我的电脑->右键->属性->高级系统设置->环境变量->(1)用户变量->新建 Path=C:\Python27(2)系统变量->编辑 ...
- Python之路Day2
-->the start 养成好习惯,每次上课的内容都要写好笔记. 第二天内容主要是熟悉int.long.float.str.list.dict.tuple这几个类的内建方法. 对于Python ...
- object-c 内存管理机制的学习
1.内存的创建和释放 让我们以Object-c世界中最最简单的申请内存方式展开,谈谈关于一个对象的生命周期.首先创建一个对象: //“ClassName”是任何你想写的类名,比如NSString NS ...
- 干Inlay的生产过程
•天线的组成 天线的材料有0.38PET和0.16以及0.3的铝箔组成. 倒封装 •将IC倒装在天线焊盘位置. •方法:先点胶水, 然后把IC对准焊盘(IC一面有凸点),通过热压把IC 固定在焊盘上. ...
- cocos2d-x中的导演、场景、层和精灵
场景(Scenes) 场景在cocos2d-x中是CCScene类实现的,是应用程序流中独立的一部分.一个cocos2dx应用程序可以有许多场景,但是在某一时刻,只有一个场景在运行. 比如,你有一个游 ...
- C++ 100款开源界面库 (10)
(声明:Alberl以后说到开源库,一般都是指著名的.或者不著名但维护至少3年以上的.那些把代码一扔就没下文的,Alberl不称之为开源库,只称为开源代码.这里并不是贬低,像Alberl前面那个系列的 ...
- Sicily-1438
一. 题意 买二送一.排序之后隔三求和,求折扣的最大值. 二. 代码 // // main.cpp // sicily-1438 // // Created by ashley o ...
- hdoj 1269 迷宫城堡(强连通分量)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269 思路分析:该问题要求判断是否每两个房间都可以相互到达,即求该有向图中的所有点是否只构成一个强连通 ...
- Home | WebScraping.com
Home | WebScraping.com We specialize in extracting data from websites, which is known as web scrapin ...