简单HTTP服务器的Java实现

在web的最初阶段是不支持web服务器与用户的交互的.也就是说web服务器不能动态的生成用户要访问的页面,web服务器提供给用户的页面都是提前生成好的.所以也说这种页面是静态页面.

比如说用户请求访问http://localhost:8088/hello1.htm, 那么web服务器从自己的想要目录下获取hello1.htm(已经存在).然后通过HTTP协议返回给用户.

下面我们来模拟一下这个过程.因为HTTP协议是应用层协议,基于TCP,所以我们用Java的socket来编写HTTP服务器.

编写HttpServer

import java.io.*;
import java.net.*;

public class HttpServer {
    private static final int port = 8088;
    private ServerSocket serverSocket = null;

    public HttpServer() throws IOException {
        serverSocket = new ServerSocket(port);
        System.out.println("HTTPServer startup OK...");
    }

    public String getRequest(Socket socket) throws IOException {
        InputStream socketIn = socket.getInputStream();
        int size = socketIn.available();
        byte[] requestBuff = new byte[size];
        socketIn.read(requestBuff);
        return new String(requestBuff);
    }

    public String getURI(String request) {
        String firstLine = request.substring(0, request.indexOf("\r\n"));
        String[] parts = firstLine.split(" ");

        return parts[1];
    }

    public String getContentType(String URI) {
        /* 决定HTTP响应正文的类型 */
        String contentType;
        if (URI.indexOf("html") != -1 || URI.indexOf("htm") != -1)
            contentType = "text/html";
        else if (URI.indexOf("jpg") != -1 || URI.indexOf("jpeg") != -1)
            contentType = "image/jpeg";
        else if (URI.indexOf("gif") != -1)
            contentType = "image/gif";
        else
            contentType = "application/octet-stream";
        return contentType;
    }

    public InputStream getResponseContent(String URI)
            throws FileNotFoundException {
        InputStream htmlInputStream = new FileInputStream(
                System.getProperty("user.dir") + "/WebRoot" + URI);
        return htmlInputStream;
    }

    public String assembleResponseHead(String URI, String contentType) {
        /* 创建HTTP响应结果 */
        // HTTP响应的第一行
        String responseFirstLine = "HTTP/1.1 200 OK\r\n";
        // HTTP响应头
        String responseHeader = "Content-Type:" + contentType + "\r\n\r\n";

        return responseFirstLine + responseHeader;
    }

    public void service() throws InterruptedException {
        while (true) {
            Socket socket;
            try {
                socket = serverSocket.accept();

                String request = getRequest(socket);
                System.out.println("HttpServer receive request:\n" + request);

                String URI = getURI(request);

                String contentType = getContentType(URI);
                OutputStream out = socket.getOutputStream();

                out.write(assembleResponseHead(URI, contentType).getBytes());

                int len = 0;
                byte[] buffer = new byte[128];
                InputStream htmlInputStream = getResponseContent(URI);
                while ((len = htmlInputStream.read(buffer)) != -1)
                    out.write(buffer, 0, len);
                Thread.sleep(1000);
                socket.close(); // 关闭TCP连接
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) throws IOException,
            InterruptedException {
        HttpServer httpServer = new HttpServer();
        // System.out.println(System.getProperty("user.dir"));
        httpServer.service();
    }

}

创建hello1.htm

然后在项目的目录/WebRoot下放置一个hello1.htm页面:

hello1.htm很简单,显示标题HelloWorld

<html>
<head>
<title>HelloWorld</title>
</head>
<body >
  <h1>Hello</h1>
</body>
</html>

访问hello1.htm

启动HTTPServer,在浏览器访问http://localhost:8088/hello1.htm,看到eclipse的Console输出

GET /hello1.htm HTTP/1.1
Host: localhost:8088
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.125 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4

这是浏览器请求的HTTP消息,包括了HTTP头,请求方式,有时也有请求正文(这里没有).

浏览器显示为:

这样简单的HTTPSever就算完成了,后续我将继续研究模拟一下Servlet的HTTP服务器.

时间: 2024-11-10 00:29:18

简单HTTP服务器的Java实现的相关文章

如何用Java编写一个简单的服务器和客户机

今天我要向大家介绍的是自己编写的一个比较简单的服务器和客户机程序,注意一下哦,比较简单.好了,闲话休提,砸门直入主题. 小编先从客户机和服务器的模型开始讲解.简单来说,我们实现的这种模型呢,我们每一个用户称为一个客户机,用户之间的通信之间需要一个中转,所有客户机的通信都依托于这个中转,很明显,这个中转,就是砸门的服务器了.整个模型比较简单明了,那么,接下来我们就直接进入实现阶段. 我们从实现服务器开始.Java提供了这样的一个类,ServerSocket.我们通过实例化它的方式来创建一个服务器.

java实现简单web服务器(分析+源代码)

在日常的开发中,我们用过很多开源的web服务器,例如tomcat.apache等等.现在我们自己实现一个简单的web服务器,基本的功能就是用户点击要访问的资源,服务器将资源发送到客户端的浏览器.为了简化操作,这里不考虑资源不存在等异常情况.web服务基于的是HTTP协议,用户在浏览器的地址栏输入要访问的地址,服务器如何得到该地址是个关键.先看下一般的HTTP请求和响应报文的一般格式: HTTP 请求报文 HTTP 响应报文 web服务器获取一个用户的连接时,会初始化一个线程和用户通信,代码如下:

基于Java实现简单Http服务器(转)

基于Java实现简单Http服务器(转) 本文将详细介绍如何基于java语言实现一个简单的Http服务器,文中将主要介绍三个方面的内容:1)Http协议的基本知识.2)java.net.Socket类.3)java.net.ServerSocket类,读完本文后你可以把这个服务器用多线程的技术重新编写一个更好的服务器.           由于Web服务器使用Http协议通信的因此也把它叫做Http服务器,Http使用可靠的TCP连接来工作,它是面向连接的通信方式,这意味着客户端和服务器每次通信

用Java编写你自己的简单HTTP服务器

来源:http://blog.csdn.net/yanghua_kobe/article/details/7296156 HTTP是个大协议,完整功能的HTTP服务器必须响应资源请求,将URL转换为本地系统的资源名.响应各种形式的HTTP请求(GET.POST等).处理不存在的文件请求,返回各种形式的状态码,解析MIME类型等.但许多特定功能的HTTP服务器并不需要所有这些功能.例如,很多网站只是想显示“建设中“的消息.很显然,Apache对于这样的网站是大材小用了.这样的网站完全可以使用只做一

tomcat解析之简单web服务器(图)

链接地址:http://gogole.iteye.com/blog/587163 之前有javaeyer推荐了一本书<how tomcat works>,今天晚上看了看,确实不错,第一眼就着迷了. 于是乎就学着书上的例子敲了敲,学会了一个简单web服务器的大概实现,当然,这个简直就无法称之为web服务器,但是也算是走进web服务器的第一步吧. 这篇文章仅限于学习记录,文笔凌乱之处,还望各位见谅. OK,下面进入正题: 开始之前,首先我们要清楚以下几个内容. 首先,一个最简单服务器包括三个部分:

一个基于AIO实现的简单web服务器

一下是一个基于AIO实现的简单web服务器,这是一个简单例子 /** * 一个简单的web 服务器<br/> * 通过浏览器输入localhost:8080/访问 * * @author Joeson * @since 2014/05 * */ public class AioServer implements Runnable { private AsynchronousChannelGroup asyncChannelGroup; private AsynchronousServerSoc

用nodejs搭建一个简单的服务器

使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安装成功 [常用命令] 切换盘符 d:进入文件夹 cd nodejs返回上一级目录 cd..清屏 cls展示目录 dir复制文件名 选中右键--复制历史操作 上箭头 执行文件 node 文件名(在文件文件夹目录中)停止命令行 ctrl+c nodejs可以使用的ECMAScript.读写文件.数据库操

简单的例子 关于Java内存管理的讲解

我想做的是,逐行读取文件,然后用该行的电影名去获取电影信息.因为源文件较大,readlines()不能完全读取所有电影名,所以我们逐行读取. 就这段代码,我想要在位置二处使用base64,然后结果呢? 两处位置都打印了,位置一得到base64,ok,没问题.当我在位置二想使用base64时,问题来了?onload队列的问题,位置二总是无法正确的获取到想要的base64,这个时候就可以考虑异步问题了. 在还没有接触到angular的时候,还真的不知道它到底有什么作用,直到我开始学习它,并且运用到它

EventMachine 系列之简单的服务器

摘要:Dota(Defence of the Ancients,远古的守护), 是指基于魔兽争霸3:冰封王座(暴雪娱乐公司出品)的多人即时对战自定义地图,可支持10个人同时连线游戏.Dota以对立的两个小队展开对战,通常是5v5,游戏目的是守护自己的远古遗迹(近卫方的生命之树.天灾方的冰封王座),同时摧毁对方的远古遗迹.DotA是目前唯一被暴雪娱乐公司官方认可的魔兽争霸RPG.Dota在大学生中的风靡程度令人咂舌,而随着玩家对游戏的理解深入,本身存在于游戏中的许多数学模型被挖掘出来进行研究.游戏