Java实现简单的站点请求模式

栏目: Java · 发布时间: 8年前

内容简介:Java实现简单的站点请求模式

Java实现简单的站点请求模式

概述

本次实现的是浏览器(客户端)访问特定站点ip和端口,自定义socket来监听该请求,解析请求内容以及做出响应。

以下是在com.yzz.tomcat下的三个类

- HttpServer:socket监听ip,接收客户端请求。

- HttpRequest:解析客户端HTTP请求。

- HttpResponse:对客户端请求做出响应。

HttpServer

await()方法这里面包括了socket的创建,连接的监听,对HTTP请求的解析以及对请求做出响应。

package com.yzz.tomcat.server;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import com.yzz.tomcat.request.HttpRequest;
import com.yzz.tomcat.response.HttpResponse;

public class HttpServer {
    //获取项目中的文件
    public static final String WEEB_ROOT = System.getProperty("user.dir")+File.separator+"webroot";
    //关闭监听字符
    public static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
    //是否监听关闭
    private boolean shutdown = false;
    /**
     * 这里是对特定ip端口进行监听
     * 监听8080端口
     * ip是本地ip
     */
public void await(){
        ServerSocket serverSocket = null;
        int port = 8080;
        try{
            serverSocket = new ServerSocket(port,100,InetAddress.getByName("127.0.0.1"));
        }catch (Exception e) {
            e.printStackTrace();
            System.out.println("serverSocket获取失败");
        }

        while(!shutdown){
            Socket socket = null;
            InputStream input = null;
            OutputStream output = null;
            try {
                //The method blocks until a connection is made.
                socket = serverSocket.accept();
                //设置读取超时时间
                socket.setSoTimeout(3000);
                //获取出入输出流
                input = socket.getInputStream();
                output = socket.getOutputStream();
                //创建HttpRequest对象,调用parse()方法来解析HTTP请求
                HttpRequest request = new HttpRequest(input);
                request.parse();
                //新建HttpResponse对象,对请求进行对应的处理
                HttpResponse response = new HttpResponse(output);
                response.setHttpRequest(request);
                //向客户端发送静态的资源
                response.sendStaticResource();
                //在做出响应后,关闭socket连接
                socket.close();
                //判断是否是客户端发来的关闭监听指令
                shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }
}

HttpRequest

这里需要特别注意的是,在读取HTTP请求内容的时候与普通的文件流有所区别,详情见注释

package com.yzz.tomcat.request;

import java.io.InputStream;

public class HttpRequest {

    //socket连接的输入流
    private InputStream inputStream;
    //统一字段标识符
    private String uri;
    //HTTP请求内容
    private StringBuffer request;

    public HttpRequest(InputStream inputStream) {
        this.inputStream = inputStream;
    }
    /**
     * 解析HTTP请求
     * 这里只是对HTTP协议的第一行的URI做了解析,其他内容这里并没有做关注
     * 注意:socket的输入流的文件流有区别,文件流可以循环读取,直到出现某一个标志位,结束
     *          但是socket的输入流不满足这种情况,当读取完成之后,流会处于等待状态,并没有结束,因为是端对端的传输,不知道
     *         客户端时候是传输完毕了,所以会处于无限期的等待状态中。
     * 解决:目前的解决办法是一次性读完所有的HTTP请求资源,这里是2048byte
     */
    public void parse() {
        request = new StringBuffer();
        try {
            if (null == inputStream)
                return;
            byte buf[] = new byte[2048];
            int len = 0;
            len = inputStream.read(buf);
            if(len != -1)
                request.append(new String(buf,0,len));
            System.out.println(request.toString());
            parseUri();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 解析URI
     */
    private void parseUri() {
        int index1;
        int index2;
        index1 = request.indexOf(" ");
        index2 = request.indexOf(" ", index1 + 1);
        if (index2 > index1)
            uri = request.substring(index1 + 1, index2);
        System.out.println("uri:"+uri);
    }

    public String getUri() {
        return uri;
    }

}

HttpResponse

响应做的比较简单,请求的资源存在就将资源通过输出流返回给客户端,否则返回404页面

package com.yzz.tomcat.response;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import com.yzz.tomcat.request.HttpRequest;
import com.yzz.tomcat.server.HttpServer;

public class HttpResponse {
    //socket连接输出流
    private OutputStream out;
    //HTTP请求对象
    private HttpRequest httpRequest;
    //缓冲byte数组长度
    public static final int BUFFER_SIZE = 1024;
    //404 URI
    public static final String PAGE_404 = "/404.html";
    public HttpResponse(OutputStream out) {
        this.out = out;
    }

    public void setHttpRequest(HttpRequest httpRequest) {
        this.httpRequest = httpRequest;
    }
    /**
     * 向客户端响应静态资源
     */
    public void sendStaticResource() {
        File file = new File(HttpServer.WEEB_ROOT, httpRequest.getUri());
        FileInputStream fis = null;
        if(!file.exists()){
            file = new File(HttpServer.WEEB_ROOT+PAGE_404);
        }
        try {
                fis = new FileInputStream(file);
                byte[] buf = new byte[BUFFER_SIZE];
                int len = 0;
                while ((len = fis.read(buf)) != -1) {
                    out.write(buf, 0, len);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(null != fis){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

演示

工程结构 Java实现简单的站点请求模式 其中静态资源存放在tomcat的webroot目录下 结果

1. 正常请求

Java实现简单的站点请求模式

2. 错误请求

Java实现简单的站点请求模式

3. 结束监听

Java实现简单的站点请求模式

总结

本次只是简单的对socket进行了利用,对于响应还没有加上HTTP规范,下片我们继续来优化。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Web Designer's Idea Book, Vol. 2

The Web Designer's Idea Book, Vol. 2

Patrick McNeil / How / 2010-9-19 / USD 30.00

Web Design Inspiration at a Glance Volume 2 of The Web Designer's Idea Book includes more than 650 new websites arranged thematically, so you can easily find inspiration for your work. Auth......一起来看看 《The Web Designer's Idea Book, Vol. 2》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具