Tianyi's Blog Tianyi's Blog
首页
  • 计算机网络
  • 操作系统
  • 计算机科学
  • Nginx
  • Vue框架
  • 环境配置
  • Java
  • JVM
  • Spring框架
  • Redis
  • MySQL
  • RabbitMQ
  • Kafka
  • Mirror Sites
  • Dev Tools
  • Docker
  • Jenkins
  • Scripts
  • Windows
  • 科学上网
  • 旅行
  • 网站日记
  • 软件
  • 电子产品
  • 杂野
  • 分类
  • 友情链接
GitHub (opens new window)

Tianyi

一直向前,永不停止
首页
  • 计算机网络
  • 操作系统
  • 计算机科学
  • Nginx
  • Vue框架
  • 环境配置
  • Java
  • JVM
  • Spring框架
  • Redis
  • MySQL
  • RabbitMQ
  • Kafka
  • Mirror Sites
  • Dev Tools
  • Docker
  • Jenkins
  • Scripts
  • Windows
  • 科学上网
  • 旅行
  • 网站日记
  • 软件
  • 电子产品
  • 杂野
  • 分类
  • 友情链接
GitHub (opens new window)
  • Java

    • web基础
    • 策略模式
    • Java基础语法
    • JavaWeb-Base
    • Optional处理空指针,这几招你会了吗?
    • 并发编程的艺术
    • 并发编程工具
    • 一个简单的 web 服务器实例
      • 这里之后要做一个压力测试
        • 单线程版本
        • 多线程版本
        • 线程池版本
        • 去除硬编码
    • 小笔记-线程池
    • 小笔记-JUC入门
  • Golang

  • JVM的奇妙世界

  • Spring

  • Spring增强封装

  • Redis

  • MySQL

  • RabbitMQ

  • Kafka

  • 分享

  • 后端
  • Java
tianyi
2023-07-30
目录

一个简单的 web 服务器实例

# 这里之后要做一个压力测试

http://localhost:9999/hello.html

# 单线程版本

/**
 * 单线程版本
 */
public class BsServer01 {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器 启动.....  ");
        System.out.println("开启端口 : 9999.....  ");
        // 1. 创建服务端ServerSocket
        ServerSocket serverSocket = new ServerSocket(9999);
        // 2. 循环接收,建立连接
        Socket accept = serverSocket.accept();
        /*
         *3. socket对象进行读写操作
         */
        //转换流,读取浏览器请求第一行
        BufferedReader readWb = new BufferedReader(new InputStreamReader(accept.getInputStream()));
        String requst = readWb.readLine();//包含URL地址
        //取出请求资源的路径
        String[] strArr = requst.split(" ");
        System.out.println(Arrays.toString(strArr));
        String path = strArr[1].substring(1);//截取请求path
        System.out.println(path);

        //----前提请求的Path与文件相对路径的Path是相同的
        FileInputStream fis = new FileInputStream(path);
        System.out.println(fis);
        byte[] bytes= new byte[1024];
        int len = 0 ;

        //向浏览器 回写数据
        OutputStream out = accept.getOutputStream();
        out.write("HTTP/1.1 200 OK\r\n".getBytes());
        out.write("Content-Type:text/html\r\n".getBytes());
        out.write("\r\n".getBytes());
        while((len = fis.read(bytes))!=-1){
            out.write(bytes,0,len);
        }

        fis.close();
        out.close();
        readWb.close();
        accept.close();

    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

# 多线程版本

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;


/**
 * 多线程版本
 */
public class BsServer02 {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器 启动.....  ");
        System.out.println("开启端口 : 9999.....  ");
        // 1. 创建服务端ServerSocket
        ServerSocket serverSocket = new ServerSocket(9999);
        // 2. 循环接收,建立连接
        while (true) {
            Socket accept = serverSocket.accept();
            /*
            3. socket对象交给子线程处理,进行读写操作
            Runnable接口中,只有一个run方法,使用lambda表达式简化格式
            */
            new Thread(() -> {
                try{
                    /*
                     *socket对象进行读写操作
                     */
                    //转换流,读取浏览器请求第一行
                    BufferedReader readWb = new BufferedReader(new InputStreamReader(accept.getInputStream()));
                    String requst = readWb.readLine();
                    //取出请求资源的路径
                    String[] strArr = requst.split(" ");
                    System.out.println(Arrays.toString(strArr));
                    String path = strArr[1].substring(1);
                    System.out.println(path);

                    //----
                    FileInputStream fis = new FileInputStream(path);
                    System.out.println(fis);
                    byte[] bytes= new byte[1024];
                    int len = 0 ;

                    //向浏览器 回写数据
                    OutputStream out = accept.getOutputStream();
                    out.write("HTTP/1.1 200 OK\r\n".getBytes());
                    out.write("Content-Type:text/html\r\n".getBytes());
                    out.write("\r\n".getBytes());
                    while((len = fis.read(bytes))!=-1){
                        out.write(bytes,0,len);
                    }

                    fis.close();
                    out.close();
                    readWb.close();
                    accept.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# 线程池版本

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


/**
 * 线程池版本
 */
public class BsServer03 {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器 启动.....  ");
        System.out.println("开启端口 : 9999.....  ");
        // 创建服务端ServerSocket
        ServerSocket serverSocket = new ServerSocket(9999);
        //创建10个线程的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(200);

        while (true) {
            Socket accept = serverSocket.accept();
            //提交线程执行的任务
            executorService.submit(()->{
                try{
                    /*
                     *socket对象进行读写操作
                     */
                    //转换流,读取浏览器请求第一行
                    BufferedReader readWb = new BufferedReader(new InputStreamReader(accept.getInputStream()));
                    String requst = readWb.readLine();
                    //取出请求资源的路径
                    String[] strArr = requst.split(" ");
                    System.out.println(Arrays.toString(strArr));
                    String path = strArr[1].substring(1);
                    System.out.println(path);

                    //----
                    FileInputStream fis = new FileInputStream(path);
                    System.out.println(fis);
                    byte[] bytes= new byte[1024];
                    int len = 0 ;

                    //向浏览器 回写数据
                    OutputStream out = accept.getOutputStream();
                    out.write("HTTP/1.1 200 OK\r\n".getBytes());
                    out.write("Content-Type:text/html\r\n".getBytes());
                    out.write("\r\n".getBytes());
                    while((len = fis.read(bytes))!=-1){
                        out.write(bytes,0,len);
                    }

                    fis.close();
                    out.close();
                    readWb.close();
                    accept.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# 去除硬编码

静态资源文件夹中放置一个server.xml

<?xml version="1.0" encoding="utf-8"?>
<server>
    <port>8080</port>
</server>
1
2
3
4
        //初始化端口
        //读取配置文件Server.xml中的端口号
        InputStream in = BsServer04.class.getClassLoader().getResourceAsStream("server.xml");
        //获取配置文件输入流
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read(in);
        //使用SAXReader + XPath读取端口配置
        Element portEle = (Element) doc.selectSingleNode("//port");
        String port = portEle.getText();

        System.out.println("服务器 启动.....  ");
        System.out.println("开启端口 : " + Integer.valueOf(port));
1
2
3
4
5
6
7
8
9
10
11
12

导入POM依赖

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.3</version>
</dependency>
<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>1.1.6</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
完善页面 (opens new window)
并发编程工具
小笔记-线程池

← 并发编程工具 小笔记-线程池→

最近更新
01
JDK
02-23
02
BadTasteCode && 优化
09-11
03
Gradle 实践操作指南及最佳实践
09-11
更多文章>
Theme by Vdoing | Copyright © 2021-2025 Tandy | 粤ICP备2023113440号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式