Web服务器的原理

时间:2019-03-15
本文章向大家介绍Web服务器的原理,主要包括Web服务器的原理使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Web服务器的原理

 

一.实现一个WEB服务器

1.新建Java项目

 

 

2.新建三个类,分别为Webserver,request,response

 

 

3.输入代码

WebServer类:

package test;

import java.io.*;

import java.net.*;

 

public class WebServer {

      /**

      * web服务器:实现200和404操作

      * 原理:

      * 服务器监听一个端口,并读取浏览器的请求信息,从该信息提取出访问的资源(这里为文件名)。并在工作目录下查找是否有该资源,有则输出资源内容,否则返回404

      * 测试方法:

      * 1、用String path=System.getProperty("user.dir");获取当前的工作目录,并在该目录下放要测试的文件

      * 2、访问127.0.0.1:8080/test.html

      */

 

     public static void main(String[] args) {

         // TODO Auto-generated method stub

         ServerSocket server = null;

         Socket s=null;

         try

         {

             server=new ServerSocket(8080,3,InetAddress.getByName("127.0.0.1"));

         }catch(Exception e)

         {

             e.printStackTrace();

         }

         while(server!=null)

         {

             try{

                 s=server.accept();

                 OutputStream output=s.getOutputStream();

                 InputStream input=s.getInputStream();

                 

                 //接收请求信息

                 Request request=new Request(input);

                 String filename=request.getUri();

                 //System.out.println(filename); 

             

                 //处理并响应请求信息

                 Response response=new Response(output,filename);

                 response.response();

             }catch(Exception e)

             {

                 e.printStackTrace();

             }

         }

     }

 }

 

Request类:

package test;

import java.io.*; 

public class Request { 

    /* 

     * 接收请求的信息,并返回资源(文件名)

     * */

    InputStream input;

    public Request(InputStream input)

    {

        this.input=input;

    }

    public String getUri() throws IOException

    { 

        String content=null;

        StringBuffer request = new StringBuffer();  

        byte[] buffer = new byte[2048];  

        int i = 0;  

          

        try {  

            i = input.read(buffer);  //读取内容并存入buffer数组中,并返回读取的的字节数。

        } catch (IOException e) {  

            e.printStackTrace();  

            i = -1;  

        }  

        //将buffer数组转换为字符串

        for(int k = 0; k < i; k++) {  

            request.append((char)buffer[k]);  

        }  

        content=request.toString(); 

    /*     

     *以下方法错误!用该返回会使浏览器不断处于请求连接状态

     * BufferedReader br=new BufferedReader(new InputStreamReader(input));

        while((str=br.readLine())!=null)

        { 

            content=content+str+"\r\n";

        }

    */    

        if(content!=null

            return getFilename(content);

        else return null;

    } 

    /*提取文件名*/

    public String getFilename(String content)

    {

        int a,b;

        a=content.indexOf(' ');

        if(a!=-1)

        {

            b=content.indexOf('?',a+1);

            if(b==-1)b=content.indexOf(' ',a+1);

            return content.substring(a+2,b);

        }

        return null;

    }

}

 

Response类:

package test;

import java.io.*;

import java.io.File;

import java.io.IOException; 

import java.io.OutputStream;

public class Response {

    /**

     * 响应并处理请求信息

     */

    public OutputStream output;

    public String filename;

    private static final int BUFFER_SIZE = 1024;

    public  Response(OutputStream output,String filename)

    {

        this.output=output;

        this.filename=filename;

    }

    public void response() throws IOException

    {

        String path=System.getProperty("user.dir");//获取当前的工作目录

        byte[] buffer = new byte[BUFFER_SIZE];  

        int ch;  

        FileInputStream fis = null;  

        //System.out.println(path+File.separator+filename);

        if(path!=null&&filename!=null)

        {

            File file=new File(path,filename);

            String str="";

            /*必须添加响应头,否则无法以html格式显示内容*/

            if(file.exists())

            {

                fis = new FileInputStream(file);  

                str = "HTTP/1.1 200 OK \r\n" +  

                 "Content-Type: text/html\r\n" +  

                 "\r\n" ;

                output.write(str.getBytes());

                ch = fis.read(buffer);                

                while(ch != -1) {  

                    output.write(buffer, 0, ch);  

                    ch = fis.read(buffer, 0, BUFFER_SIZE);  

                }  

            }

            else

            {

                 str = "HTTP/1.1 404 File Not Found \r\n" +  

                 "Content-Type: text/html\r\n" +  

                 "Content-Length: 100\r\n" +  

                 "\r\n" +  

                 "<h1>404 File Not Found!</h1>";

                output.write(str.getBytes());

            }

        }

        output.close();

    }

}

 

4.新建一个HTML文件

 

 

①输入代码:

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>HELLO</title>

</head>

<body>

<p>Hello World!</p>

</body> 

</html>

 

②运行

5.实验结果:

打开网页http://localhost:8080/test.html 显示结果:

 

 

②输入一个错误的地址:

 

 

 

二.Web服务器工作原理

1.web服务器工作原理图解

 

 

首先我们暂时不考虑HTTP协议的各种请求方式,我们先跟着**Web服务器工作原理总体描述01)这张图,将一次Web服务的工作流程过一遍,我们假设以浏览器作为客户端

(1) 用户做出了一个操作,可以是填写网址敲回车,可以是点击链接,可以是点击按键等,接着浏览器获取了该事件。

(2) 浏览器与对端服务程序建立TCP连接。

(3) 浏览器将用户的事件按照HTTP协议格式**打包成一个数据包,其实质就是在待发送缓冲区中的一段有着HTTP协议格式的字节流。

(4) 浏览器确认对端可写,并将该数据包推入Internet,该包经过网络最终递交到对端服务程序。

(5) 服务端程序拿到该数据包后,同样以HTTP协议格式解包,然后解析客户端的意图。

(6) 得知客户端意图后,进行分类处理,或是提供某种文件、或是处理数据。

(7) 将结果装入缓冲区,或是HTML文件、或是一张图片等。

(8) 按照HTTP协议格式将(7)中的数据打包

(9) 服务器确认对端可写,并将该数据包推入Internet,该包经过网络最终递交到客户端。

(10) 浏览器拿到包后,以HTTP协议格式解包,然后解析数据,假设是HTML文件。

(11) 浏览器将HTML文件展示在页面

以上为Web服务器工作基本原理。其实不难发现,这仅仅只是一个简单的网络通信。我们应该深信,作为一个服务器,其根本的工作无非有三个

 1.接收数据 2. 发送数据 3. 数据处理

Web服务器的本质就是 接收数据 ⇒ HTTP解析 ⇒ 逻辑处理 ⇒ HTTP封包 ⇒ 发送数据

高级的服务器无非就是将这三个部分更加细致的设计了。

 

2.Web服务器之提供静态文件工作原理图解

Web服务器最主要的功能是提供静态的文件。日常的上网浏览大多是网页浏览,少数时候才会有一些数据的提交操作。因此,我们结合上一张图示来重点讲解在GET请求下的Web服务器工作原理。

 

 

其他流程基本不变,着重在于红色与蓝色部分。

(1) 当用户点击一个网页链接或浏览器加载一些资源(css,jpg …)时产生。

(6) 服务程序解包后,确定其为GET请求,并且是对该服务器上的某一资源的请求。首先服务程序会去确认该路径是否存在,再确定该路径的文件是否可以获取。

(7-1) 如果请求的路径有误,或者该资源不能被用户获取,则返回错误提示页面。很多服务器的错误页面只有404,更专业的应该是将错误分类并返回对应的错误代码页面。

(7-2) 如果该路径合法且文件可以被获取,那么服务程序将根据该文件类型进行不同的装载过程,记录其类型作为(8)HTTP协议中对应的返回类型,并加入响应头。

 

假设以点击一个页面链接为例,浏览器首先将HTML文件请求过来,再以同样的流程对HTML文件中包含的资源文件路径进行依次请求。

 

 

3.Web服务器之数据提交工作原理图解

仅仅只是网页的浏览并不能满足所有人的需求,客户端与服务器应当是有数据交互的。

即使单方面的资源请求任然是网络的主力军。

我们应该清楚的知道,数据提交对于用户来说有什么作用。

(1) 资源上传 (2) 登陆验证 (3) API接口调用 (4) 远程指令等

数据提交使得用户的操作性有了质的飞跃,它使得HTTP短连接获取静态文件的方式提升到了动态交互的层次上。该性质也催化出各式各样的编程语言、框架。例如PHPJavaWeb

如果你留意目前主流的那些大型服务器,你会发现再高级再牛逼的东西实际是也是最基础的东西建造的。那么我们还可以顺便学习一下最古老的动态技术CGI

 

其他流程基本不变,着重在于红色与蓝色部分。

(1) 用户提交数据,假设用户点击一个按键提交填好的信息。在(3)中将以POST格式写入,并填入提交至服务端的可执行程序的路径。

(6) 服务端将参数与该CGI绑定,复制进程,用管道传递参数和接收结果

(7) 子进程执行CGI,接收(6)父进程传来的参数,运算完成返回结果。

最后父进程将结果装入静态模板文件,放入缓冲区

 

参考:https://blog.csdn.net/qq_36359022/article/details/81666221

 

上一页 下一页

原文地址:http://www.manongjc.com/article/73104.html