Web服务器的原理

Web服务器的原理
学号:201631062509
姓名:杨菓
一 、Web服务器的实现

新建三个类:WebSever,Request,Response,并分别写下下列代码。

1.WebServer.java文件

   1 package webserver;
 2 
 3 import java.io.*;
 4 import java.net.*;
 5 
 6 public class WebServer {
 7 
 8     /**
 9      * web服务器:实现200和404操作
10      * 原理:
11      * 服务器监听一个端口,并读取浏览器的请求信息,从该信息提取出访问的资源(这里为文件名)。并在工作目录下查找是否有该资源,有则输出资源内容,否则返回404
12      * 测试方法:
13      * 1、用String path=System.getProperty("user.dir");获取当前的工作目录,并在该目录下放要测试的文件
14      * 2、访问127.0.0.1:8080/test.html
15      */
16     public static void main(String[] args) {
17         // TODO Auto-generated method stub
18         ServerSocket server = null;
19         Socket s=null;
20         try
21         {
22             server=new ServerSocket(8080,3,InetAddress.getByName("127.0.0.1"));
23         }catch(Exception e)
24         {
25             e.printStackTrace();
26         }
27         while(true)
28         {
29             try{
30                 s=server.accept();
31                 OutputStream output=s.getOutputStream();
32                 InputStream input=s.getInputStream();
33                 
34                 //接收请求信息
35                 Request request=new Request(input);
36                 String filename=request.getUri();
37                 //System.out.println(filename);
38                 
39                 //处理并响应请求信息
40                 Response response=new Response(output,filename);
41                 response.response();
42 
43             }catch(Exception e)
44             {
45                 e.printStackTrace();
46             }
47         }
48     }
49 
50 }

2.Request.java

   1 package webserver;
 2 import java.io.*;
 3 public class Request {
 4     /*
 5      * 接收请求的信息,并返回资源(文件名)
 6      * */
 7     InputStream input;
 8     public Request(InputStream input)
 9     {
10         this.input=input;
11     }
12     public String getUri() throws IOException
13     {
14         String content=null,str=null;
15         StringBuffer request = new StringBuffer();  
16         byte[] buffer = new byte[2048];  
17         int i = 0;  
18           
19         try {  
20             i = input.read(buffer);  //读取内容并存入buffer数组中,并返回读取的的字节数。
21         } catch (IOException e) {  
22             e.printStackTrace();  
23             i = -1;  
24         }  
25         //将buffer数组转换为字符串
26         for(int k = 0; k < i; k++) {  
27             request.append((char)buffer[k]);  
28         }  
29         content=request.toString();
30     /*    
31      *以下方法错误!用该返回会使浏览器不断处于请求连接状态
32      * BufferedReader br=new BufferedReader(new InputStreamReader(input));
33         while((str=br.readLine())!=null)
34         {
35             content=content+str+"\r\n";
36         }
37     */    
38         if(content!=null)
39             return getFilename(content);
40         else return null;
41     }
42     /*提取文件名*/
43     public String getFilename(String content)
44     {
45         int a,b;
46         a=content.indexOf(' ');
47         if(a!=-1)
48         {
49             b=content.indexOf('?',a+1);
50             if(b==-1)b=content.indexOf(' ',a+1);
51             return content.substring(a+2,b);
52         }
53         return null;
54     }
55 }

3.Response.java

   1 package webserver;
 2 
 3 import java.io.*;
 4 import java.io.File;
 5 import java.io.IOException;
 6 import java.io.OutputStream;
 7 
 8 public class Response {
 9     /**
10      * 响应并处理请求信息
11      */
12     public OutputStream output;
13     public String filename;
14      private static final int BUFFER_SIZE = 1024; 
15     public  Response(OutputStream output,String filename)
16     {
17         this.output=output;
18         this.filename=filename;
19     }
20     public void response() throws IOException
21     {
22         String path=System.getProperty("user.dir");//获取当前的工作目录
23         byte[] buffer = new byte[BUFFER_SIZE];  
24         int ch;  
25         FileInputStream fis = null;  
26         //System.out.println(path+File.separator+filename);
27         if(path!=null&&filename!=null)
28         {
29             File file=new File(path,filename);
30             String str="";
31             /*必须添加响应头,否则无法以html格式显示内容*/
32             if(file.exists())
33             {
34                 fis = new FileInputStream(file);  
35                 str = "HTTP/1.1 200 OK \r\n" +  
36                  "Content-Type: text/html\r\n" +  
37                  "\r\n" ;
38                 output.write(str.getBytes());
39                 ch = fis.read(buffer);                
40                 while(ch != -1) {  
41                     output.write(buffer, 0, ch);  
42                     ch = fis.read(buffer, 0, BUFFER_SIZE);  
43                 }  
44             }
45             else
46             {
47                  str = "HTTP/1.1 404 File Not Found \r\n" +  
48                  "Content-Type: text/html\r\n" +  
49                  "Content-Length: 100\r\n" +  
50                  "\r\n" +  
51                  "<h1>404 File Not Found!</h1>"; 
52                 output.write(str.getBytes());
53             }
54         }
55         output.close();
56     }
57 }
新建一个HTML文件,并写下如下代码:

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>HELLO</title>

</head>

<body>

<p>Hello World!</p>

</body> 

</html>

运行结果

输入正确地址

输入不正确地址

二、 Web服务器原理
1.Web服务器工作原理图解
首先我们暂时不考虑HTTP协议的各种请求方式,我们先跟着这张图,将一次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短连接获取静态文件的方式提升到了动态交互的层次上。该性质也催化出各式各样的编程语言、框架。例如PHP,JavaWeb。
如果你留意目前主流的那些大型服务器,你会发现再高级再牛逼的东西实际是也是最基础的东西建造的。那么我们还可以顺便学习一下最古老的动态技术CGI
其他流程基本不变,着重在于红色与蓝色部分。
(1) 用户提交数据,假设用户点击一个按键提交填好的信息。在(3)中将以POST格式写入,并填入提交至服务端的可执行程序的路径。
(6) 服务端将参数与该CGI绑定,复制进程,用管道传递参数和接收结果
(7) 子进程执行CGI,接收(6)父进程传来的参数,运算完成返回结果。
最后父进程将结果装入静态模板文件,放入缓冲区
4.动态技术
我们得明白,Web服务器是以短连接为主,并且获取的数据到达浏览器的那一刻一定是静态的不变的。那么所谓动态实际是指两种情况
服务端产生:
(1) 用户POST提交数据到某个程序,程序根据该数据作为参数运行,得出结果并装入静态的模板页面中,返回该静态页面。但对于用户来说,同一个页面,做了一个操作后数据不一样了。好了,这就是动态页面。(CGI原理)
(2) PHP的原理是,用户GET请求一个php后缀的文件,服务器先执行该php后缀文件中的PHP代码,将结果填入代码的位置,再返回。当然也可以提交数据参与运算再返回。
客户端产生:
(1) 用户GET请求一个JavaScript文件,服务端不做任何运算返回该静态文件。浏览器收到该JS文件,在本地执行并更新页面。
(2) 用户POST提交数据到服务端,服务端根据该提交的数据指令返回静态文件,浏览器收到后执行并更新。

转载于:https://www.cnblogs.com/Yy-Gg/p/10537937.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值