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

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

内容简介: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规范,下片我们继续来优化。


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

查看所有标签

猜你喜欢:

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

ACM国际大学生程序设计竞赛亚洲区预选赛真题题解

ACM国际大学生程序设计竞赛亚洲区预选赛真题题解

郭炜 / 电子工业 / 2011-7 / 49.00元

ACM国际大学生程序设计竞赛(ACM International Collegiate Programming Contest,简称ACM/ICPC)是世界上历史最悠久,规模最大、最具声望的程序设计竞赛,一直受到众多国际知名大学的重视,全球著名IT公司更是争相招募竞赛的优胜者。 该项赛事分为各大洲预选赛和全球总决赛两个阶段。北京大学多次在亚洲区预选赛中负责命题工作,是中国在ACM/ICPC命......一起来看看 《ACM国际大学生程序设计竞赛亚洲区预选赛真题题解》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具