使用java手写一个简单的web服务器(一)

使用java手写一个简单的web服务器(一)

前言:初来乍到 ,新手小白,根据所学的知识进行填充,有些原创有些借鉴,如有错误及侵犯,欢迎指教交流。

​ 我们的第一个Web服务器将是多线程的,所收到的每个Request消息将交由单独的线程进行处理。这使得服务器可以并发地为多个客户服务, 或者是并发地服务于一个客户的多个请求.当创建一个新线程时,需要向线程的构造函数传递实现了Runnable 接口的类的一个实例(即通过实现接口Runnable来实现多线程)。

package com.zhu;

import java.util.*;
import java.io.*;
import java.net.*;

public class WebServer {


    //主线程负责监听某个端口,当收到TCP连接请求时,将创建一个新的socket负责与TCP连接
    //并创建新的线程负责通过该连接的消息传递

    public static void main(String args[]) {


        //设置一个端口号,这里可以选择大于1024的任意端口作为web服务器的监听端口,因为小于1024的端口号通常被知名端口占用了

        int port = 6789;


        //创建监听端口,为了等待TCP连接请求
        ServerSocket server = null;

        Socket socket = null;

        try {
            server = new ServerSocket(port);

            System.out.println("Web Server is listening on port:" + server.getLocalPort());

            //由于web服务器不间断提供服务,所以我们放到一个无穷的循环体中
            while (true) {
                socket = server.accept();
                //启动线程,让HttpRequest在单独的一个线程中处理HTTP请求
                new HttpRequest(socket).run();
            }

        } catch (Exception e) {
            System.out.println(e);
        }
    }

}



//处理Http请求
class HttpRequest implements Runnable {

    Socket socket;

    //回车换行,根据http规范,回车换行作为Response消息头部行的结束
    static String CRLF = "\r\n";

    public HttpRequest(Socket socket) throws Exception {
        this.socket = socket;
    }


    //Runnable接口中的run()方法不能抛出异常,所以我们定义processRequest()
    public void run() {
        try {
            processRequest();
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    //流程请求
    public void processRequest() throws Exception {


        //通过socket的输入流读取消息
        InputStream is = socket.getInputStream();

        //输出流不需要任何包装,因为我们将向输出流直接写入bytes
        DataOutputStream os = new DataOutputStream(socket.getOutputStream());

        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        //即从input stream中获得请求行
        String requestLine = br.readLine();//读取一行  遇到   回车换行符  结束

        System.out.println();

        System.out.println(requestLine);

        String headerLine = null;

        //首部行和实体行之间有一个空行作为分割体
        //使用循环读取所有头部行,读取头部行的长度如果为0,表示读出了一个空行
        while ((headerLine = br.readLine()).length() != 0) {

            System.out.println(headerLine);

        }

        

       //关闭输入输出流以及socket
        os.close();
        br.close();
        socket.close();
        
        //至此,已经完成了Web服务器将显示HTTP Request消息的内容
        //可以通过访问 localhost:6789,在java控制台中查看请求报文

    }

}

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手写一个 JavaWeb 服务器,需要掌握以下步骤: 1. 创建一个 ServerSocket 对象,指定服务器监听的端口号; 2. 在一个循环中,不断接收客户端的请求,每次接收到一个请求,就创建一个 Socket 对象与客户端进行连接; 3. 创建一个线程池,来处理客户端的请求。每当有一个客户端连接时,就将该客户端的请求交给线程池去处理; 4. 在线程池中,根据请求的 URL,读取对应的静态资源文件,并将其返回给客户端; 5. 如果请求的是动态资源,即需要执行 Java 代码生成内容的,那么就需要在服务器端编写对应的 Servlet。在处理请求时,根据 URL 匹配对应的 Servlet,并调用其相应的方法生成内容,并将其返回给客户端; 6. 在处理完客户端请求之后,需要关闭连接。 下面是一个简单JavaWeb 服务器的示例代码: ```java import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class SimpleServer { private final static int PORT = 8080; private final static String WEB_ROOT = "src/main/resources/"; public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(PORT); ExecutorService threadPool = Executors.newFixedThreadPool(10); System.out.println("Server is running at http://localhost:" + PORT); while (true) { Socket socket = serverSocket.accept(); Runnable task = () -> { try { String request = getRequest(socket.getInputStream()); String url = parseUrl(request); if (url.equals("/")) { url = "/index.html"; } String filePath = WEB_ROOT + url; File file = new File(filePath); if (file.exists() && file.isFile()) { String contentType = guessContentType(filePath); byte[] content = readFile(file); sendResponse(socket.getOutputStream(), "HTTP/1.1 200 OK", contentType, content); } else { sendResponse(socket.getOutputStream(), "HTTP/1.1 404 Not Found", "text/html", "404 Not Found".getBytes()); } } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }; threadPool.execute(task); } } private static String getRequest(java.io.InputStream input) throws IOException { byte[] buffer = new byte[1024]; int len = input.read(buffer); return new String(buffer, 0, len); } private static String parseUrl(String request) { int index1, index2; index1 = request.indexOf(' '); if (index1 != -1) { index2 = request.indexOf(' ', index1 + 1); if (index2 > index1) { return request.substring(index1 + 1, index2); } } return null; } private static byte[] readFile(File file) throws IOException { try (FileInputStream fis = new FileInputStream(file)) { byte[] buffer = new byte[fis.available()]; fis.read(buffer); return buffer; } } private static String guessContentType(String fileName) { if (fileName.endsWith(".html") || fileName.endsWith(".htm")) { return "text/html"; } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) { return "image/jpeg"; } else if (fileName.endsWith(".gif")) { return "image/gif"; } else if (fileName.endsWith(".png")) { return "image/png"; } else if (fileName.endsWith(".css")) { return "text/css"; } else if (fileName.endsWith(".js")) { return "application/javascript"; } else { return "application/octet-stream"; } } private static void sendResponse(OutputStream output, String status, String contentType, byte[] content) throws IOException { output.write((status + "\r\n").getBytes()); output.write(("Content-Type: " + contentType + "\r\n").getBytes()); output.write(("Content-Length: " + content.length + "\r\n").getBytes()); output.write("\r\n".getBytes()); output.write(content); output.flush(); } private static void sendResponse(OutputStream output, String status, String contentType, String content) throws IOException { sendResponse(output, status, contentType, content.getBytes()); } } ``` 这个示例代码实现了一个简单的静态资源服务器。当客户端请求一个 URL 时,服务器会读取对应的静态资源文件,如果找到了文件,则将其返回给客户端。如果找不到文件,则返回一个 404 Not Found 响应。在这个示例中,我们使用了线程池来处理客户端请求,通过解析 HTTP 请求报文,来获取客户端请求的 URL,然后再根据 URL 来读取对应的资源文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值