Web服务器简介:Web服务器是指驻留于因特网上某种类型计算机的程序。当web浏览器(客户端)连到服务器上并请求文件时,服务器将处理该请求并将文件发送到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。服务器使用HTTP(超文本传输协议)进行信息交流,这就是人们常把它们称为HTTPD服务器的原因。
web服务器的作用:Web服务器不仅能够存储信息,还能在用户通过Web浏览器提供的信息的基础上运行脚本和程序。
Web服务器可以解析HTTP协议。当Web服务器接收到一个HTTP请求,会返回一个HTTP响应,例如送回一个HTML页面。为了处理一个请求Web服务器可以响应一个静态页面或图片,进行页面跳转或者把动态响应的产生委托给一些其它的程序例如CGI脚本,JSP脚本,servlets,asp脚本,服务器端JavaScript,或者一些其它的服务器端技术。无论它们的目的如何,这些服务器端的程序通常产生一个HTML的响应来让浏览器可以浏览。
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服务器工作基本原理。其实不难发现,这仅仅只是一个简单的网络通信。我们应该深信,作为一个服务器,其根本的工作无非有三个
接收数据 2. 发送数据 3. 数据处理
而Web服务器的本质就是 接收数据 ⇒ HTTP解析 ⇒ 逻辑处理 ⇒ HTTP封包 ⇒ 发送数据
高级的服务器无非就是将这三个部分更加细致的设计了。
在eclipse上搭建简单的服务器:
request类的代码:
package webServerTest; 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 webServerTest; 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(); } }
webSever的代码:
package webServerTest; 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(); } } } }
运行结果:
ps:在运行过程中可能会出现空指针异常的情况,那是因为端口被占用导致的ServerSocket对象不能被实例化,在命令行窗口中关掉占用端口的进程就可以了。
我的理解:web服务器的工作步骤可分为建立连接—请求过程—应答过程—关闭连接。建立连接就是web服务器与浏览器建立的一种连接。在上述代码中具体表现为ServerSocket对象的实例化。请求过程就是服务器接受来自浏览器的请求并作出相应处理的过程。上述代码中表现为request类对请求信息的处理。应答过程就是服务器返回给浏览器的信息内容。就是response中的内容。最后就是关闭连接的过程。我觉得上面的代码并没有体现。