Java实现简易Tomcat服务器(清晰易懂)

来源:互联网 发布:2级钢筋弯勾 算法 编辑:程序博客网 时间:2024/06/03 23:42

Tomcat服务器是一个轻量级的Java代码实现的WEB服务器。这篇文章将会讲述如何用Java实现一个简易版的Tomcat服务器。

简单的讲,简易原理是这样的:

1. Tomcat开始运行之后,会在主机上开一个端口(默认是80端口),在所开辟的端口上运行一个ServerSocket,执行accept()方法等待浏览器访问。

2. 浏览器访问目标主机的80端口,ServerSocket的accept()方法返回一个运行在服务器端的socket,该socket有getInputStream()方法和getOutputStream方法,可以获得浏览器对服务器发送的内容和响应浏览器并发送内容。

3. 浏览器收到服务器响应的内容,通过浏览器解释,内容显示在用户眼前。

注意:

1. 浏览器发送给服务器的访问请求符合HTTP协议。

2. 浏览器可以像服务器请求一个HTML页面,也可以请求图片,若HTML页面中导入了图片或者css,js,则这些内容也会像服务器请求,服务器会根据文件名,对浏览器进行响应,若该文件在服务器目录中找不到,则返回404错误。

3. 本简易Tomcat服务器只适用于静态资源。

4. 本简易Tomcat分为两个类,Server类以及Handler类,Server类接收请求,然后创建子线程,到Handler类中去处理浏览器发送的请求,并反馈。

代码及注释如下:

package com.yykj;import java.io.*;import java.net.ServerSocket;import java.net.Socket;public class Server {    public static void main(String[] args) {        Server server = new Server();        server.startServer();    }    public  void startServer(){        try {            ServerSocket serverSocket = new ServerSocket(80);//开启80端口            System.out.println("服务器启动>>> 80端口");            while(true){//开启一个永远的循环,一直等待客户访问80端口                Socket socket = serverSocket.accept();                Thread thread = new Thread(new Handler(socket));//当有客户访问时,开辟一个新线程处理该请求                System.out.println("收到新请求");                thread.start();            }        } catch (IOException e) {            e.printStackTrace();        }    }}

Handler类:

package com.yykj;import java.io.*;import java.net.Socket;//请求处理程序public class Handler implements  Runnable {    private Socket socket;    private OutputStream outputStream;    private InputStream inputStream;    private BufferedReader reader;    private PrintWriter writer;    private static String WEB_ROOT = "C:\\Users\\Administrator\\Desktop\\web";//服务器储存文件目录    public Handler(Socket socket){        this.socket = socket;    }    @Override    public void run(){        try{            inputStream = socket.getInputStream();//服务器到客户的输出流            outputStream = socket.getOutputStream();//客户到服务器的输入流            reader = new BufferedReader(new InputStreamReader(inputStream));//包装后的输入缓冲字符流            writer = new PrintWriter(new OutputStreamWriter(outputStream));//包装后的输出缓冲字符流            String msg;//接收客户端请求的临时字符串            StringBuffer request = new StringBuffer();//将请求拼接成完整的请求            while((msg = reader.readLine()) != null && msg.length() > 0){                request.append(msg);                request.append("\n");//HTTP协议的格式            }            String[] msgs = request.toString().split(" ");//HTTP协议以空格为分隔符            //msgs[1]代表了HTTP协议中的第二个字符串,是浏览器请求的文件名/*            if(msgs[1].endsWith(".ico")){//.ico文件是浏览器页面的图标文件,是浏览器默认会向服务器发送的请求                writer.println("HTTP/1.1 200 OK");//如果服务器不打算对客户端发送.ico结尾的文件,可以这一写,然后直接返回,跳过发送该文件的过程                writer.println("Content-Type: text/html;charset=UTF-8");                writer.close();                //如果不发送,就直接返回                return;            }*/            //将服务器目录下被请求的文件读入程序            FileInputStream fileInputStream = new FileInputStream(new File(WEB_ROOT + msgs[1]));            byte[] fileBuffer = new byte[1024];//可能是二进制文件,所以需要用byte数组做缓冲            int length = 0;            while((length = fileInputStream.read(fileBuffer)) != -1){                outputStream.write(fileBuffer, 0, length);//向客户端浏览器发送文件            }            outputStream.close();            inputStream.close();            reader.close();            fileInputStream.close();        }catch (IOException e){            //如果抛出异常,在这里基本上是未找到被请求文件,所以返回404            writer.write("HTTP/1.1 404 ERROR:FILE NOT FINDED");            writer.close();        }    }}

3 0
原创粉丝点击