1.4 浏览器与Web服务器的交互

下面以访问百度网站www.baidu.com为例,介绍浏览器与Web服务器的交互过程。

(1)当用户第一次访问www.baidu.com时,浏览器并不知道www.baidu.com的IP地址,将请求报文发向DNS服务器,DNS服务器查询到www.baidu.com对应的IP地址后,将地址发回浏览器,浏览器将这个IP地址缓存到本地,下次访问www.baidu.com时将直接读取缓存中的IP地址。然后浏览器根据IP地址向www.baidu.com对应的Web服务器发送请求报文。

(2)Web服务器接收请求报文后,解析请求报文,将请求的资源存放到响应报文中,将响应报文发回浏览器。

(3)浏览器接收响应报文,解析响应报文,将请求到的资源显示在浏览器页面上。此时完成一个交互过程。

这里可以写一个小程序模仿浏览器和Tomcat的交互。

import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.net.InetAddress;  
import java.net.ServerSocket;  
import java.net.Socket;  
 
/** 
* @author yezl 
* @date 2018年4月26日 下午1:51:35 
* @version 1.0.0 
*/ 
public class SimpleTomcat {  
    public static void main(String[] args) throws IOException { 
        ServerSocket serverSocket = null;  
        int port = 8050;     
        serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1") );  
        while(true)  { 
            Socket socket = null;  
            InputStream input = null;  
            OutputStream output = null;      
            socket = serverSocket.accept();  
            input = socket.getInputStream();  
            output = socket.getOutputStream();     
            //获取浏览器发送的请求, 这里是在控制台输出 
            dorequest(input);      
            //回应浏览器, 这里返回一个字符串 
            String responseMessage = "<h1>Hello world, I am a simple server</h1>";  
            output.write(responseMessage.getBytes() );     
            socket.close();  
        } 
        //serverSocket.close();  
    }   
    /** 
    * 输出浏览器发送的请求 
    * @author yezl 
    * @date 2018年4月26日 
    * @version 1.0.0 
    * @param input 
    */ 
    public static void dorequest(InputStream input)   { 
        // 接受请求 
        StringBuffer request = new StringBuffer(2048);  
        int i;  
        byte[] buffer = new byte[2048] ;  
        try { 
            i = input.read(buffer);  
        } catch(IOException e)   { 
            e.printStackTrace();  
            i = -1;  
        } 
        for(int j = 0; j < i; j++)   { 
            request.append((char) buffer[j] );  
        } 
        System.out.print(request.toString() );  
    } 
}

上面这个Java类比较简单,用Java自带的Socket(套接字)进行编程,模拟了服务器应答请求的全过程。首先服务器监听本地的8050端口,127.0.0.1表示本地IP,input指向网络流的输入,output指向网络流的输出,利用dorequest( )函数解析输入流的内容,并且在控制台输出,然后写入“<h1>Hello world,I am a simple server</h1>”到输出流output,使之返回到发出请求的客户端浏览器,并显示在页面上。

①运行上面的程序,在浏览器中输入http://127.0.0.1:8050/,按回车键,待出现图1.16所示的画面就表示运行成功了。

②在控制台可以看到图1.17所示的输出,这些就是浏览器发送给服务器端的请求。

图1.16 浏览器显示服务器发送的“Hello world”

图1.17 浏览器发送给服务器端的请求