Http服务器版本1.

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HttpServerV1 {
    //http基于tcp实现,基于HTTP基本格式实现
    public ServerSocket serverSocket = null;

    public HttpServerV1(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动");
        ExecutorService executorService = Executors.newCachedThreadPool();
        while (true) {
            //1、获取连接
            Socket clientSocket = serverSocket.accept();
            //2、处理连接
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        process(clientSocket);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }


    private void process(Socket clientSocket) throws IOException {
        //由于HTTP是文本协议,用字符流处理
        try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))) {
            //按照HTTP协议来进行操作
            //1、读取请求并解析
            // 1.1 解析首行  三个部分按照空格切分
            String firstLine = bufferedReader.readLine();
            String[] firstLineTokens = firstLine.split(" ");
            String method = firstLineTokens[0];
            String url = firstLineTokens[1];
            String version = firstLineTokens[2];

             //1.2 解析header 按行读取 按照冒号空格表示键值对
            Map<String,String> headers = new HashMap<>();
            String line = "";
            while ((line = bufferedReader.readLine()) != null && line.length() != 0) {
                //不能使用冒号来区分 referer字段内容可能包含冒号
                String[] headerTokens = line.split(": ");
                headers.put(headerTokens[0],headerTokens[1]);
            }
//
//            // 1.3 解析body 先不考虑
            System.out.printf("%s %s %s\n",method, url, version);
            for (Map.Entry<String,String> entry : headers.entrySet()) {
                System.out.println(entry.getKey()+ ": "+ entry.getValue());
            }
            System.out.println();
            //2、根据请求计算响应  返回hello
            String resp = "";
            if (url.equals("/ok")) {
                bufferedWriter.write(version + " 200 OK\n");
                resp = "<h1>hello</h1>";
            } else if (url.equals("/notfound")) {
                bufferedWriter.write(version + " 404 Not Found\n");
                resp = "<h1>not found</h1>";
            }else if (url.equals("/seeother")) {
                bufferedWriter.write(version + " 303 see other\n");
                bufferedWriter.write("Location: https://blog.csdn.net/yufy0528\n");
                resp = "";
            } else {
                bufferedWriter.write(version+"200 OK\n");
                resp = "<h1>default</h1>";
            }

            // 3. 把响应写回到客户端
            bufferedWriter.write("Content-Type: text/html\n");
            bufferedWriter.write("Content-Length: " + resp.getBytes().length + "\n"); // 此处的长度, 不能写成 resp.length(), 得到的是字符的数目, 而不是字节的数目
            bufferedWriter.write("\n");
            bufferedWriter.write(resp);
            // 此处这个 flush 就算没有, 问题也不大. 紧接着
            // bufferedWriter 对象就要被关闭了. close 时就会自动触发刷新操作.
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        HttpServerV1 httpServerV1 = new HttpServerV1(9090);
        httpServerV1.start();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值