手写高性能http服务器,手写一个最迷你的Web服务器

相信大家对Tomcat服务器应该都很熟悉了,我们几乎每天都会用它,它的安装目录结构大致如下:

AAffA0nNPuCLAAAAAElFTkSuQmCC

今天我们就仿照Tomcat服务器来手写一个最简单最迷你版的web服务器,仅供学习交流。

1. 在你windows系统盘的F盘下,创建一个文件夹webroot,用来存放前端代码。

2. 创建一个简单的Java项目,项目结构如下图:

AAffA0nNPuCLAAAAAElFTkSuQmCC

3. 代码介绍:

(1)ServerThread.java 核心代码,主要用于web文件的读取与解析等。代码如下:package server;

import java.io.*;

import java.net.Socket;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

/**

* @ClassName: ServerThread

* @Description:

* @Author: liuhefei

* @Date: 2019/6/23

* @blog: https://www.imooc.com/u/1323320/articles

**/

public class ServerThread implements Runnable {

private static Map contentMap = new HashMap<>();

//可以参照Tomcat的web.xml配置文件

static {

contentMap.put("html", "text/html");

contentMap.put("htm", "text/html");

contentMap.put("jpg", "image/jpeg");

contentMap.put("jpeg", "image/jpeg");

contentMap.put("gif", "image/gif");

contentMap.put("js", "application/javascript");

contentMap.put("css", "text/css");

contentMap.put("json", "application/json");

contentMap.put("mp3", "audio/mpeg");

contentMap.put("mp4", "video/mp4");

}

private Socket client;

private InputStream in;

private OutputStream out;

private PrintWriter pw;

private BufferedReader br;

private static final String webroot = "F:\\webroot\\";    //此处目录,你可以自行修改

public ServerThread(Socket client){

this.client = client;

init();

}

private void init(){

//获取输入输出流

try {

in = client.getInputStream();

out = client.getOutputStream();

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void run() {

try {

gorun();

} catch (Exception e) {

e.printStackTrace();

}

}

private void gorun() throws Exception {

//读取请求内容

BufferedReader reader = new BufferedReader(new InputStreamReader(in));

String line = reader.readLine().split(" ")[1].replace("/", "\\");  //请求的资源

if(line.equals("\\")){

line += "index.html";

}

System.out.println(line);

String strType = line.substring(line.lastIndexOf(".")+1, line.length());  //获取文件的后缀名

System.out.println("strType = " + strType);

//给用户响应

PrintWriter pw = new PrintWriter(out);

InputStream input = new FileInputStream(webroot + line);

//BufferedReader buffer = new BufferedReader(new InputStreamReader(input));

pw.println("HTTP/1.1 200 ok");

pw.println("Content-Type: "+ contentMap.get(strType)  +";charset=utf-8");

pw.println("Content-Length: " + input.available());

pw.println("Server: hello");

pw.println("Date: " + new Date());

pw.println();

pw.flush();

byte[] bytes = new byte[1024];

int len = 0;

while ((len = input.read(bytes)) != -1){

out.write(bytes, 0, len);

}

pw.flush();

input.close();

pw.close();

reader.close();

out.close();

client.close();

}

}

(2)HttpServer.java   (普通版)服务端package server;

import java.io.*;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Date;

/**

* @ClassName: HttpServer

* @Description:  服务端

* @Author: liuhefei

* @Date: 2019/6/23

* @blog: https://www.imooc.com/u/1323320/articles

**/

public class HttpServer {

public static void main(String[] args) throws IOException {

//启动服务器,监听9005端口

ServerSocket server = new ServerSocket(9005);

System.out.println("服务器启动,监听9005端口....");

while (!Thread.interrupted()){

//不停接收客户端请求

Socket client = server.accept();

//开启线程

new Thread(new ServerThread(client)).start();

}

server.close();

}

}

(2)HttpServer1.java  (线程池版)服务端package server;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

/**

* @ClassName: HttpServer

* @Description:  服务端

* @Author: liuhefei

* @Date: 2019/6/23

* @blog: https://www.imooc.com/u/1323320/articles

**/

public class HttpServer1 {

public static void main(String[] args) throws IOException {

//创建线程池

ExecutorService pool = Executors.newCachedThreadPool();

//启动服务器,监听9005端口

ServerSocket server = new ServerSocket(9005);

System.out.println("服务器启动,监听9005端口....");

while (!Thread.interrupted()){

//不停接收客户端请求

Socket client = server.accept();

//向线程池中提交任务

pool.execute(new ServerThread(client));

}

server.close();

pool.shutdown();

}

}

4. 将一个具有index.html的静态页面文件拷入到我们创建的webroot目录下。相关的静态web资源代码可以到源码之家下载或是自己编写。

5. 启动web服务,启动HttpServer.java 或HttpServer1.java都可以,服务启动之后将会监听9005端口。

即可看到效果,我的效果如下:

AAffA0nNPuCLAAAAAElFTkSuQmCC

控制台打印如下:

AAffA0nNPuCLAAAAAElFTkSuQmCC

到这里,一个简单的Web服务器就完成了。

仅供参考学习,感谢诸君的支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值