一个简单的web服务器例子

一个简单的web容器小例子,功能十分简单,只能访问静态资源,对于新手来说还是有一定的意义。主要分三个类

1、server类:主要功能开启socketServer,阻塞server,接收socket访问,解析request,创建request,作出响应

public class TestServer1 {

    private boolean shutdown = false;

    // web目录webroot
    public static final String WEB_ROOT = System.getProperty("user.dir")
            + File.separator +  "WebRoot";

    public static final String SHUTDOWN_COMMAND = "/SHUTDOWN";

    public static void main(String[] args) {
        TestServer1 server = new TestServer1();
        server.await();
    }

    public void await() {

        // 第一步、创建出serverSocket监听本机8080端口
        ServerSocket server = null;
        int port = 8080;
        try {
            server = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
        } catch (Exception e) {
            e.printStackTrace();
        } 

        // 第二步、轮询阻塞住socketServer
        while(!shutdown) {
            Socket socket = null;
            InputStream input = null;
            OutputStream output = null;

            try {
                socket = server.accept();
                input = socket.getInputStream();
                output = socket.getOutputStream();

                // 第三步、创建出request,解析request请求
                Request req = new Request(input);
                req.parseRequest();

                // 第四步、创建response
                Response response = new Response(output);
                response.setRequest(req);

                // 第五步、发送简单静态资源,关闭socket结束本次会话
                response.sendStaticRes();
                socket.close();

                // 关闭指令
                shutdown = req.getUri().equals(SHUTDOWN_COMMAND);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

当然了上面的是最简单的实现,也不能实现多线程,实际上的web容器肯定会创建一个线程池来接收请求

2、request 主要的工作解析input流,封装成request

class Request {

    private InputStream input;

    private String uri;

    public Request(InputStream input) {
        this.input = input;
    }

    /**
     * 解析request请求内容
     * GET /index.html HTTP/1.1
     *    Accept: text/html, application/xhtml+xml, *//*
     *    Accept-Language: zh-CN
     *    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; MALCJS; rv:11.0) like Gecko
     *    Accept-Encoding: gzip, deflate
     *    Host: localhost:8080
     *    DNT: 1
     *    Connection: Keep-Alive     *    Cookie: 这个地方应该如果有cookie,如果有session还有jsessionId的
     */
    public void parseRequest() {     // 为什么只获取2048个字符,这是因为request请求内容的长度,出于安全或者其他方面的考虑,在浏览器端和服务器端都会做这么一个限制。 
        StringBuffer buffer = new StringBuffer(2048);
        byte[] bytes = new byte[2048];
        int i;
        try {
            i = input.read(bytes);
        } catch (IOException e) {
            e.printStackTrace();
            i=-1;
        }

        for(int k=0; k<i; k++) {
            buffer.append((char)bytes[k]);
        }
        System.out.println(buffer.toString());
        uri = parseUri(buffer.toString());
    }

    /**
     * GET /index.html HTTP/1.1 uri的位置
     * @param reqStr
     * @return
     */
    private String parseUri(String reqStr) {
        int index1, index2;
        index1 = reqStr.indexOf(‘ ‘);
        if (index1 != -1) {
          index2 = reqStr.indexOf(‘ ‘, index1 + 1);
          if (index2 > index1)
            return reqStr.substring(index1 + 1, index2);
        }
        return null;
    }

    public String getUri() {
        return uri;
    }

}

解析成的http请求的具体内容,作为web开发人员应该要熟悉每个字段的意义,这个请求是浏览器本身按照http协议封装的一个请求,能够手写出这个请求当然更好。

3、response 通过request的uri找到对应的资源对请求作出响应,实际的情况肯定是有静态和动态资源例如servlet\filter等等,但是这里只是做了简单的静态的处理了

class Response {

    private OutputStream output;

    private Request request;

    public Response(OutputStream output) {
        this.output = output;
    }

    public void setRequest(Request req) {
        this.request = req;
    }

    /**
     * 简单处理静态资源
     * @throws IOException
     */
    public void sendStaticRes() throws IOException {

        FileInputStream fis = null;
        try {
            File staticFile = new File(TestServer1.WEB_ROOT, request.getUri());
            if(staticFile.exists()) {
                fis = new FileInputStream(staticFile);
                int i = 0;
                byte[] buf = new byte[1024];          // 流的对拷
                i = fis.read(buf, 0, 1024);
                while(i!=-1) {
                    output.write(buf, 0, i);
                    i = fis.read(buf, 0, 1024);
                }
            } else {
                // file not found 404
                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>";
                output.write(errorMessage.getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(fis!=null)
                fis.close();
            fis = null;
        }
    }
}

同样响应内容你也应该要熟悉哪些组成部分

HTTP/1.1 200 OK  //响应行
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122

<html>
<head>
<title>Test</title>
</head>
<body>
This my page
</body>
</html>

至此一个简单的web容器就写好了,能够访问webRoot目录下的静态资源。

可以通过浏览器访问,也可以通过telnet端进行访问。在cmd命令行下telnet localhost 8080,就会连接上socketServer,然后就会等待输入,自然我们输入对应的请求报文,回车响应内容就出现了。

以上原创文章出自老罗家的树博客地址:http://www.cnblogs.com/TimBing/

时间: 2024-10-25 18:00:00

一个简单的web服务器例子的相关文章

自己动手模拟开发一个简单的Web服务器

开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的Web服务器来体会一下. 一.请求-处理-响应模型 1.1 基本过程介绍 每一个HTTP请求都会经历三个步凑:请求-处理-响应:每当我们在浏览器中输入一个URL时都会被封装为一个HTTP请求报文发送到Web服务器,而Web服务器则接收并解析HTTP请求报文,然后针对请求进行处理(返回指定的HTML页面

使用 Nodejs 搭建一个简单的Web服务器

使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块.路径解析模块.以及301重定向问题,下面我们就简单讲一下如何来搭建一个简单的Web服务器. 作为一个Web服务器应具备以下几个功能: 1.能显示以.html/.htm结尾的Web页面 2.能直接打开以.js/.css/.json/.text结尾的文件内容 3.显示图片资源 4.自动下载以.apk/.

如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个iPhone/iPad开发者,能够自己写一个简单的web服务器将是很有用的. 例如,你可能希望在软件启动时显示一些来自服务器的更新,或者在服务器端保存一些用户数据.除了你的想象力,没有什么能限制你了. 在第一篇中,我们将会一步一步的建立一个web服务器,基于promo code system(促销码系

自己模拟的一个简单的web服务器

首先我为大家推荐一本书:How Tomcat Works.这本书讲的很详细的,虽然实际开发中我们并不会自己去写一个tomcat,但是对于了解Tomcat是如何工作的还是很有必要的. Servlet容器是如何工作的 servlet容器是一个复杂的系统.不过,一个servlet容器要为一个servlet的请求提供服务,基本上有三件事要做: 1,创建一个request对象并填充那些有可能被所引用的servlet使用的信息,如参数.头部. cookies.查询字符串. URI 等等.一个 request

一个简单的web服务器

static void Main(string[] args) { IPAddress localAddress = IPAddress.Loopback;//获取本机的ip地址 IPEndPoint endPoint =new IPEndPoint(localAddress, 49155); Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); socket.Bind

一个简单的Web服务器-支持Servlet请求

上接 一个简单的Web服务器-支持静态资源请求,这个服务器可以处理静态资源的请求,那么如何处理Servlet请求的呢? 判断是否是Servlet请求 首先Web服务器需要判断当前请求是否是Servlet请求. 像Tomcat,通过解析HTTP报文拿到请求url后,就可以根据web.xml来查找是否有匹配的Servlet,如果有匹配则认定为是一个有效的Servlet请求,然后将request,response传给对应的servlet的service()方法. 这里既然要实现一个简单的Web服务器,

(一)一个简单的Web服务器

万丈高楼平地起,首先我们必须了解 超文本传输协议(HTTP) 以后才能够比较清晰的明白web服务器是怎么回事. 1. 浅析Http协议 HTTP是一种协议,允许web服务器和浏览器通过互联网进行来发送和接受数据.它是一种请求和响应协议.客户端请求一个文件而服务器响应请求.HTTP使用可靠的TCP连接--TCP默认使用80端口.第一个HTTP版是HTTP/0.9,然后被HTTP/1.0所替代.正在取代HTTP/1.0的是当前版本HTTP/1.1,它定义于征求意见文档(RFC) 2616,可以从ht

学习用node.js建立一个简单的web服务器

一.建立简单的Web服务器涉及到Node.js的一些基本知识点: 1.请求模块 在Node.js中,系统提供了许多有用的模块(当然你也可以用JavaScript编写自己的模块,以后的章节我们将详细讲解),如http.url等.模块封装特定的功能,提供相应的方法或属性,要使用这些模块,需要先请求模块获得其操作对象. 例如要使用系统的http模块,可以这样写: var libHttp = require('http'); //请求HTTP协议模块 这样,以后的程序将可以通过变量libHttp访问ht

Tomcat学习笔记(一)一个简单的Web服务器

内容为<深入剖析Tomcat>第一章重点,以及自己的总结,如有描述不清的,可查看原书. 一.HTTP协议: 1.定义:用于服务器与客户端的通讯的协议,允许web服务器和浏览器通过互联网进行发送和接收数据.是一种请求和响应协议,使用可靠的TCP协议,TCP协议的端口为80,是一种面向连接的协议. 2.HTTP协议请求的三个组成部分:这三部分之间用回车换行符(CRLF)隔开 请求部分:方法(GET/POST等7种,其他的很少用,书上有介绍)[空格,该部分内容以空格隔开] 统一资源标识符URI[空格